I have a table recording states and timestamps, like this one:
| id | serialno | state | timestamp |
|---|---|---|---|
| 1 | 100100100 | True | 01:02:02 |
| 2 | 100100100 | True | 01:02:14 |
| 3 | 100100100 | False | 01:02:15 |
| 4 | 100100100 | True | 01:02:26 |
| 5 | 100100100 | True | 01:02:46 |
And I would need to get the time spent within each state, whereas the end time for each state is the timestamp value of the next record; like this:
| id | serialno | state | timestamp | duration |
|---|---|---|---|---|
| 1 | 100100100 | True | 01:02:02 | 12 |
| 2 | 100100100 | True | 01:02:14 | 1 |
| 3 | 100100100 | False | 01:02:15 | 11 |
| 4 | 100100100 | True | 01:02:26 | 20 |
| 5 | 100100100 | True | 01:02:46 | (ongoing) |
And the expected result would be:
| serialno | state | duration |
|---|---|---|
| 100100100 | True | 12 + 1 + 20 = 42 |
| 100100100 | False | 11 |
I tried using the LAG() and LEAD() window-functions, but could not get the expected result.
Could you please help me?
Thanks a lot in advance!
>Solution :
you can use window function lead() like so:
with cte as (
select serialno
, state
, lead(timestamp) over (partition by serialno order by timestamp) - timestamp as duration
from DeviceState
)
select serialno, state
, sum(duration) as duration
from cte
group by serialno, state
output:
| serialno | state | duration |
|---|---|---|
| 100100100 | t | 00:00:33 |
| 100100100 | f | 00:00:11 |