我有一个表的简化版本,其中包含有关仪器状态的信息。我试图找到每个状态的总时间。 DateAdded是一个时间戳,表示状态的开始,下一个条目是第一个状态的结束和下一个状态的开始。
+--------------------+-----------+-------------------------+ | InstrumentStatusId | Statename | DateAdded | +--------------------+-----------+-------------------------+ | 737062 | alarming | 2018-03-14 00:37:51.423 | | 737064 | running | 2018-03-14 00:38:12.410 | | 737065 | running | 2018-03-14 00:38:21.443 | | 737149 | alarming | 2018-03-14 01:45:03.433 | | 737152 | error | 2018-03-14 01:45:39.443 | | 737153 | idle | 2018-03-14 01:45:42.457 | | 737154 | running | 2018-03-14 01:45:42.460 | | 737155 | idle | 2018-03-14 01:45:45.490 | | 737356 | running | 2018-03-14 04:20:21.350 | | 737382 | idle | 2018-03-14 04:36:03.433 | | 737383 | running | 2018-03-14 04:36:03.437 | | 737384 | idle | 2018-03-14 04:36:06.463 | | 737890 | running | 2018-03-14 10:13:00.313 | | 738201 | alarming | 2018-03-14 11:10:41.120 | | 738204 | idle | 2018-03-14 11:11:11.120 | | +--------------------+-----------+-------------------------+
我无法找出考虑多个相同状态并计算状态之间时差的解决方案。我见过类似的问题,但无法找到帮助我的解决方案。
我有sqlfiddle来播放数据。
答案 0 :(得分:2)
这个答案解释了#34;状态"与statename
同义。
我认为你只需要每个状态的第一条记录。为此,请在结果上使用lag()
,然后使用lead()
,然后使用聚合:
select statename,
sum(datediff(second, dateadded, next_dateadded)) as total_seconds
from (select s.*,
lead(dateadded) over (order by dateadded) as next_dateadded
from (select s.*, lag(statename) over (order by dateadded) as prev_statename
from instrumentstatus s
) s
where prev_statename is null or prev_statename <> statename
) s
group by statename;
Here是一个SQL小提琴。