Reputation: 2031
I have a question about comparing date ranges. I have a table that hold a state log of a machine. The state can be 0 or 1. In addition I have the date when the machine state change started and when it ended
START_DATE | END_DATE | STATE
For example:
START_DATE | END_DATE | STATE
2019-05-28 07:12:43 2019-05-29 09:12:43 1
2019-05-29 09:12:43 2019-06-01 08:12:43 0
2019-06-11 10:12:43 2019-06-12 16:12:43 1
2019-06-12 16:12:43 2019-06-12 17:12:43 0
I want to make a report that iterate through each WW (work week) and check what average state was on that WW.
My problem is that a state change could have happened on WW22 and ended on WW24 so when I GROUP BY WW I get no values on WW23 because there was no start or end state on WW23. But on WW23 that machine was on state 0 because it started on WW22 and ended on WW24 but through all the this time the state was 0.
It seems that I cant use GROUP BY WW to solve it. I may need to check START_DATE and END_DATE on cases there is no records on WW23. to add something like:
CASE WHEN WW BETWEEN START_DATE AND END_DATE THEN...
But im not sure how to loop on the WW without using GROUP BY.
I use SQL ORACLE
Thanks.
Upvotes: 0
Views: 110
Reputation: 14848
I hope I understood correctly. It would be good if You showed us your query and tell us how you count average state and where these weeks come from. Anyway here is query which generates all weeks for year 2019 and joins with your log
.
select to_char(wsd, 'iw') week, wsd, start_date, end_date, state
from (
select trunc(date '2019-01-01', 'iw') + level * 7 - 7 wsd
from dual
connect by trunc(date '2019-01-01', 'iw') + level * 7 <= date '2020-01-01')
left join log on wsd < end_date and start_date < wsd + 7
Interesting is this range:
week week_start_date log_start log_end state
21 2019-05-20
22 2019-05-27 2019-05-28 07:12:43 2019-05-29 09:12:43 1
22 2019-05-27 2019-05-29 09:12:43 2019-06-01 08:12:43 0
23 2019-06-03
24 2019-06-10 2019-06-11 10:12:43 2019-06-12 16:12:43 1
24 2019-06-10 2019-06-12 16:12:43 2019-06-12 17:12:43 0
25 2019-06-17
I don't know how you count average state for weeks 22 and 24. Maybe it is weighted average of substracted times, maybe somehow other. But it's not important, now you have row for week 23, with missing state
.
If this means that previous value is valid for this week use:
nvl(state, lag(state) over (order by wsd))
or
coalesce(state, lag(state) over (order by wsd), 0)
when you want 0
as default value when we also miss previous week(s). If two weeks are missing add ignore nulls
to lag
.
Then you can group data by weeks and count average values.
Upvotes: 1