I have a table with eventTime and status as columns as shown below.
eventTime status 2020-03-01 09:00 TRUE 2020-03-01 10:00 TRUE 2020-03-01 11:00 FALSE 2020-03-01 12:00 FALSE 2020-03-01 13:00 TRUE 2020-03-01 14:00 FALSE
I need to produce time range during which status remains the same as shown below.
startEventTime endEventTime status 2020-03-01 09:00 2020-03-01 11:00 TRUE 2020-03-01 11:00 2020-03-01 13:00 FALSE 2020-03-01 13:00 2020-03-01 14:00 TRUE 2020-03-01 14:00 NULL FALSE
Appreciate if anyone can help on how to do this in query?
Advertisement
Answer
This is a gap-and-islands problem. In this version, you seem to want the times to “tile” with no gaps. For this version, the simplest method is probably lag()
and lead()
:
select t.eventTime as startTime, lead(t.eventTime) over (order by t.eventTime) as endTime, t.status from (select t.*, lag(status) over (order by eventTime) as prev_status from t ) t where prev_status is null or prev_status <> status;
This works by taking the first row where the status changes (using the lag()
). When the intermediate rows are filtered out, it gets the next start time for the end time.