Finding closest time before/after another time - filter

I have a database of time's that are not necessarily exact to the specified time. For example, if I want to pick 12:00 PM and my columns have times in column A:
[9:00 AM, 11:55 AM, 2:00 PM, 6:00 PM],
The closest before would be 11:55 AM, and closest after would be 2:00 PM. My attempt at the code:
=MAXIF(A:A, A:A, 12:00)
=MINIF(A:A, A:A, 12:00)
But to no avail, anythoughts?

You want the max where the time is less than or equal to the criteria and the Min for the time greater than or equal to the criteria:
=MAXIFS(A:A, A:A,"<=12:00")
=MINIFS(A:A, A:A,">=12:00")

Related

How to correctly find intervals between other intervals

I need to come up with an algorithm that can find free intervals on the timeline.
There is a time scale. From 00:00 to 24:00. Initially, when there are no vacancies, all the time is free, and the free interval is (0...1440) (in minutes).
For example, we add a vacancy, I mean that we set the working time for example from 08:00 to 21:00.
Now we will already have 2 free intervals. From 00:00 to 08:00. And from 21:00 to 24:00.
I'll attach pictures below to make it clear what I mean.
*Default variant
*Intervals of vacancies (working hours) may overlap
*Intervals of vacancies can be set without restrictions on the number, and intersect with anything, most importantly within 24 hours (1 day)
The result that I expect: Initially, we have an array with 1 free interval from 0 to 1440 (in minutes), we call the function and pass working time to it, and at the output we get an updated array of intervals, in which there are already 2 intervals. Then we can add 1 more working time, and the output function will always give us the actual array with the correct number of intervals and the free time of the intervals themselves
For writing code I use swift, but I will understand the solution in Python or similar
I really hope for your help! I hope at least that the community will help put me on the right path, at the moment, I can't figure out which way to go. :(
Turn intervals into pairs of start/end events, sort the events by time, then run through the list and keep a count of how many more start than end.
Any stretch of time where the two are equal becomes an interval in your answer.
Here is an explanatory example. Suppose we have the following intervals:
04:00 - 09:00
15:00 - 20:00
08:00 - 12:00
We get the following list of events from them.
04:00 start
09:00 end
15:00 start
20:00 end
08:00 start
12:00 end
Add 2 more to bookend the day
00:00 analysis_start
24:00 analysis_end
Which get sorted into:
00:00 analysis_start
04:00 start
08:00 start
09:00 end
12:00 end
15:00 start
20:00 end
24:00 analysis_end
And now we process them to come up with the following counts of open intervals:
00:00 - 04:00 0
04:00 - 08:00 1
08:00 - 09:00 2
09:00 - 12:00 1
12:00 - 15:00 0
15:00 - 20:00 1
20:00 - 24:00 0
And now the answer is where our tally was 0:
00:00 - 04:00
12:00 - 15:00
20:00 - 24:00
One possible way to do it could be to have an array of size 1440 (number of minutes). You can initialize all to 0 indicating all are free minutes.
For each vacancy interval you need to add, flip the values from 0 -> 1 in that interval, where 1 indicates working minute.
Whenever you need the array, you can iterate through the array and find "collections" of 0s and 1s for free-time and vacancies.
However, this is a very crude way of doing this and every query (update and select) takes linear time. You can do much better performancewise if you implement this whole thing as a segment tree (Read RMQ - range minimum query) where time complexity of your updates and selects will be logarithmic. Take this decision based on number of updates and selects and how you want your performance of code. eg. If total queries are ~10k, you need not go for segment tree. If they be ~10^5 or more, then you should.

Rolling Average Calculation per month - Dax Measure

I need to calculate ASMP which is Average Shipped per Month per Period.
Count of shipped / 12 (months in year), calculated each month or for period.
Count of records in a period on from table1, where 'ship_date' is not empty / divided by 12 (months in a year).
This is a rolling calculation. As the period length is increased, the count increases.
Example: Jan count is 5, Feb count is 6, Mar count is 2. If the calculation is executed in March, the sum is 13 / 12 = ASMP of 1.08. In April the count is 5, which increases the count. The ASMP for April is 1.5.
Any assistance on creating a calculation would be great
In PBI Desktop go to the Modeling tab and select Quick measures. Then in the Calculation dropdown select Rolling average, assign the Base value and Date fields and set Period to Months. That's all it needs!

DAX Query ( Using FIlter and MAX function ), calculate Total Sales for the last running 30 days

I am new to DAX and encountered a measure as below,
30 Day Running Total = CALCULATE([Total Sales],
FILTER (ALL (Dates), Dates[Date]>(Dates[Date]) -30 && Dates[Date] <= (Dates[Date] )))
i.e. to calculate Total Sales for last 30 days in a cumulative way for the data from 1st January 2018 to 30 December 2021, the above measure i am not able to understand
My understanding is as below, please let me know where I am moving in wrong direction
FILTER ( ALL(Dates) -> Removes all filters means take date from minimum to maximum from the complete table and i.e. between 1st January 2018 till 30-december-2021
Dates[Date]>MAX(Dates[Date]) -30 -> "Takes Total Sales from the current row in table minus 30 days".
For example if the DAX calculation is on 30th January 2018 then it considers all the total sales from 1st January 2018 till 30th January 2018
Then why do we need to mention another filter Dates[Date] <= MAX(Dates[Date] )?
Thanks in advance for your time
Regards
Sumit Malik
Sumit your main concern seem to be Point (3)
why do we need to mention another filter Dates[Date] <= MAX(Dates[Date] )?
Your doubt is correct, if the data is clean, you do not need to define that upper-bound filter because theoretically considering sales from 30 days ago, there should not be sales after today.
Unfortunately, often data is dirty and there might be Sales in the future. Therefore, defining an upper-bound is a best-practice to avoid this kind of dirty data issues. Remember that in software engineering you program thinking the worst-case scenario, therefore, defining an upper bound does not harm :)

How to store periodicity in Oracle?

Which column type should be used to store a periodicity in Oracle?
Daily: time, e. g. "14:00"
Weekly: day of week, time, e. g. "Mon 14:00"
Monthly: day of month, time, e. g. "24 14:00"
Yearly: month, day, time, e. g. "12-24 14:00"
Week of year: calendar week, day, time, e. g. "W01 Mon 14:00"
Especially because of the calendar week I guess storing a pattern as text in ISO 8601 format could work. Or is there a better solution that works e. g. on timestamps?
The intent is only to store a pattern in the database. This pattern will then be used to create a periodicity for dates in a given time interval.
Example using Jodatime in Java:
Start DateTime: 2017-01-01
End DateTime: 2017-01-03
Periodicity: Daily, 02:00 - 06:00
(this is what my question is about, i. e. how to store it)
In Java the following intervals will be created using these data, the created intervals will not be stored in the database, they'll be only processed:
2017-01-01 02:00 - 2017-01-01 06:00
2017-01-02 02:00 - 2017-01-02 06:00

Business opening hours grouping algorithm

I have row of data like this that represent a business opening hours
day / opentime / closetime / isOpen
0 09:00:00 17:00:00 true
1 09:00:00 17:00:00 true
2 08:00:00 17:00:00 true
3 09:00:00 17:00:00 true
4 09:00:00 17:00:00 true
5 false
6 09:00:00 17:00:00 true
with day being an Integer from 0-6 (mon to sunday) and iOpen
Before Re-inventing the wheel and start thinking on a new algorithm I would like to know if there already some algo that would do something similar to this:
MON - TUE 9am - 5pm
WED 8am - 5pm
THU - FRI 9am - 5pm
SUN 9am - 5pm
basically grouping the day that have the opening and closing time together ?
I'm not asking for a ready to go algorithm but more of an advice to where to look if there is already something similar that has been done.
ps: bonus question. Is the way I store the data efficient to achieve my goal ?
This is a fairly straightforward algorithm. Just write down in code what you would do as a human.
As a human, when I look at the data you give me, I start with Monday, and I write down the open/close times on a sheet of paper and write "Monday" next to them. Then I look at Tuesday. If Tuesday has the same open/close times as the previous day, then I simply go to where the time was already written on my paper and add "Tuesday" right next to Monday. I keep doing this until I find an open/close time that is not the same as the previous day's. In that case, I go to a new line on my paper and write down the new open/close times and continue on like this until the end.
If I were to program this in C, I would use an array of structs, where the struct merely had the open time, the close time, and an array of character arrays (ie, an array of strings) to store the dates associated with those hours. (Note: there could be more efficient ways of storing this, but this seems good enough for your purposes)

Resources