我有一个带有跟踪两个日期列的表的sql后端。这两列称为OnTime和OffTime。列的格式为小日期时间。该表由一个带有VB形式应用程序的arduino微控制器填充,当检测到电压时,该应用程序将在OnTime列中插入日期,并在电压被移除时填充OffTime日期。我需要编写一个sql查询,它可以收集每个开关时间戳之间检测到的总时间电压。查询应该类似于
SELECT (get times) FROM tableA WHERE OnTime >= @sometime AND OffTime <= @Sometime.
这将允许我运行关于检测到电压的总分钟的报告。我熟悉使用Datediff()
函数获取时间,但我不确定以这种方式汇总多个datediff()
。
示例数据:
| ID | OnTime | OffTime |
|----|------------------|------------------|
| 1 | 2017-01-01 09:36 | null |
| 2 | null | 2017-01-01 10:36 |
| 3 | 2017-01-07 05:36 | null |
| 4 | null | 2017-01-07 6:36 |
其中Id,ontime和Offtime是列。
期望的结果是总时间为120分钟
答案 0 :(得分:2)
您可以使用老式的方式组合行:
WITH testdata (ID, OnTime, OffTime) AS (
SELECT 1, '2017-01-01 09:36', null UNION
SELECT 2, null, '2017-01-01 10:36' UNION
SELECT 3, '2017-01-07 05:36', null UNION
SELECT 4, null, '2017-01-07 6:36'
), on_off_time AS (
SELECT a.ID, a.OnTime, MIN(b.OffTime) AS OffTime
FROM testdata a
INNER JOIN testdata b ON b.OffTime > a.OnTime
GROUP BY a.ID, a.OnTime
)
SELECT SUM(DATEDIFF(MINUTE, OnTime, OffTime))
FROM on_off_time
或使用LAG
函数(SQL Server 2012或更高版本):
WITH testdata (ID, OnTime, OffTime) AS (
SELECT 1, '2017-01-01 09:36', null UNION
SELECT 2, null, '2017-01-01 10:36' UNION
SELECT 3, '2017-01-07 05:36', null UNION
SELECT 4, null, '2017-01-07 6:36'
), on_off_time AS (
SELECT ID, LAG(OnTime, 1, NULL) OVER (ORDER BY COALESCE(OnTime, OffTime)) AS OnTime, OffTime
FROM testdata
)
SELECT SUM(DATEDIFF(MINUTE, OnTime, OffTime))
FROM on_off_time
WHERE OffTime IS NOT NULL
答案 1 :(得分:1)
考虑表
ID | OnTime | OffTime
---|--------------------|--------------
1|2018-02-12 08:00:00 |null
2|null |2018-02-12 09:00:00
3|2018-02-13 07:00:00 |null
4|null |2018-02-13 09:00:00
您可以执行以下操作:
WITH Ons AS
(
SELECT ID,
ID + 1 AS IDPlusOne,
OnTime
FROM Dates
WHERE NOT OnTime IS NULL
)
,
Offs AS
(
SELECT ID,
OffTime
FROM Dates
WHERE NOT OffTime IS NULL
)
SELECT Ons.ID,
Offs.ID,
DateDiff(MINUTE, Ons.OnTime, Offs.OffTime) as DiffInMinutes
FROM Ons INNER JOIN Offs ON Ons.IDPlusOne = Offs.ID
导致
ID | ID | DiffInMinutes
---|----|---------------
1| 2|60
3| 4|120
但是你的设计很不幸,因为它需要记录 严格按顺序排列。我强烈建议在同一记录中保存两个日期时间
答案 2 :(得分:0)
如果您的条目始终与其ID一致,您可以使用这种简单的方法来获取每个数据点之间的时间:
SELECT ID,DATEDIFF(MINUTE, Ontime, (SELECT Offtime FROM yourtable t2 where t2.ID = t.ID+1)) AS 'Minutes on, per period'
FROM yourtable t
WHERE Ontime is not null;
您可以根据需要进行扩展,例如通过这样的总结
SELECT SUM(Minutes) AS 'Total minutes on, all periods'
FROM (
SELECT ID,DATEDIFF(MINUTE, Ontime, (SELECT Offtime FROM yourtable t2 where t2.ID = t.ID+1)) AS 'Minutes'
FROM yourtable t
WHERE Ontime is not null
) AS Subtable
如果你想尝试这个例子,我在这里做了一个小提琴:http://sqlfiddle.com/#!6/9db41/18
答案 3 :(得分:0)