Reputation: 63
I'm trying to calculate how long a machine was in a specific state then sum by hour. The state is only recorded on change so we can assume it was in the same state until changed.
I was trying to use partition, but I don't think that is the correct approach.
My table structure ordered desc:
+----------+-------------------------+
| state_id | t_stamp |
+----------+-------------------------+
| 0 | 2020-06-01 10:44:06.663 |
| 2 | 2020-06-01 10:43:56.660 |
| 0 | 2020-06-01 10:43:06.653 |
| 2 | 2020-06-01 10:42:56.653 |
| 0 | 2020-06-01 10:41:36.643 |
| 3 | 2020-06-01 10:41:26.640 |
| 0 | 2020-06-01 10:41:16.640 |
| 2 | 2020-06-01 10:40:56.637 |
| 0 | 2020-06-01 10:40:06.630 |
| 3 | 2020-06-01 10:39:56.630 |
+----------+-------------------------+
What I'm trying to get to:
+----------+------------------+
| state_id | duration_seconds |
+----------+------------------+
| 2 | 10 |
| 0 | 50 |
+----------+------------------+
Upvotes: 1
Views: 296
Reputation: 14062
You can use Lead function.
select state_id, sum(elapsed) as duration_seconds
from (
select
t_stamp,
state_id,
lead(t_stamp) over(order by t_stamp) - t_stamp as elapsed
from tablename
) t
group by state_id
Upvotes: 1
Reputation: 222622
You can use window functions, then aggregation:
select
state_id,
sum(datediff(second, t_stamp, lead_t_stamp)) duration_second
from (
select
t.*,
lead(t_stamp) over(order by t_stamp) lead_t_stamp
from mytable t
) t
where lead_t_stamp is not null
group by state_id
order by state_id
This demo on DB Fiddle with your uample data returns:
state_id | duration_second -------: | --------------: 0 | 190 2 | 40 3 | 20
Upvotes: 2