时间总和

时间:2018-03-16 15:39:31

标签: sql sql-server

我有一个表的简化版本,其中包含有关仪器状态的信息。我试图找到每个状态的总时间。 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来播放数据。

1 个答案:

答案 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小提琴。