Skip to content
Advertisement

Finding time range for column value change in SQL

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.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement