【发布时间】:2016-04-12 19:29:56
【问题描述】:
我们有一个表格,用于存储我们系统中某些设定点的警报。我正在尝试编写一个查询,该查询首先获取两个日期之间的差异(分布在两行中),然后将所有日期差异相加,以获得设定点处于警报状态的时间量的总和。
我们有一个数据库,我已经完成了类似的操作,但在这种情况下,startTime 和 endTime 都在同一行中。在这种情况下,这是不够的
一些示例数据
| Row | TagID | SetPointID | EventLogTime | InAlarm |
-------------------------------------------------------------------------------------
| 1 | 1 | 2 | 2016-01-01 01:49:18.070 | 1 |
| 2 | 1 | 1 | 2016-01-01 03:23:39.970 | 1 |
| 3 | 1 | 2 | 2016-01-01 03:23:40.070 | 0 |
| 4 | 1 | 1 | 2016-01-01 08:04:01.260 | 0 |
| 5 | 1 | 2 | 2016-01-01 08:04:01.370 | 1 |
| 6 | 1 | 1 | 2016-01-01 11:40:36.367 | 1 |
| 7 | 1 | 2 | 2016-01-01 11:40:36.503 | 0 |
| 8 | 1 | 1 | 2016-01-01 13:00:30.263 | 0 |
结果
| TagID | SetPointID | TotalTimeInAlarm |
------------------------------------------------------
| 1 | 1 | 6.004443 (hours) |
| 1 | 2 | 5.182499 (hours) |
本质上,我需要做的是获取每个标签和每个设定点的开始时间和结束时间,然后我需要获取警报的总时间。我觉得 CTE 可能会有所帮助,但我不确定。
我相信伪查询逻辑会类似于
Define @startTime DATETIME, @endTime DATETIME
SELECT TagID,
SetPointID,
ABS(First Occurrence of InAlarm = True (since last occurrence WHERE InAlarm = False)
- First Occurrence of InAlarm = False (since last occurrence WHERE InAlarm = True))
-- IF no InAlarm = False use @endTime.
GROUP BY TagID, SetPointID
【问题讨论】:
-
输出应该是什么样的?
-
基本上,最后,它只是:
TagID | SetPointID | TotalTimeInAlarm -
您能否详细说明第 1 点是如何得到 0.2501851 的?请写下公式,比如这个时间加上那个时间减去那个时间等等。
-
下一个问题。你用的是什么版本的sql server?如果您在 2012+ 年,答案将非常重要
-
@Jdsfighter:这就是精神!现在,如果您以
inAlarm = 0开头会发生什么?如果inAlarm = 1有两个或多个连续记录会发生什么?如果系列以inAlarm = 1结尾会发生什么?
标签: sql sql-server tsql common-table-expression