SQL在更大的时间跨度内计算多个时间差
我有一个sql后端和一个跟踪两个日期列的表。这两列分别称为On Time和OffTime。列的格式为小日期时间。该表由arduino微控制器和附带的VB表单应用程序填充,当检测到电压时,该应用程序将在OnTime列中插入一个日期,当电压消除时,填充一个OffTime日期。我需要编写一个sql查询,它可以收集在每个打开和关闭时间戳之间检测到的总时间电压。查询应该类似于SQL在更大的时间跨度内计算多个时间差,sql,sql-server,date,datetime,sql-server-2017,Sql,Sql Server,Date,Datetime,Sql Server 2017,我有一个sql后端和一个跟踪两个日期列的表。这两列分别称为On Time和OffTime。列的格式为小日期时间。该表由arduino微控制器和附带的VB表单应用程序填充,当检测到电压时,该应用程序将在OnTime列中插入一个日期,当电压消除时,填充一个OffTime日期。我需要编写一个sql查询,它可以收集在每个打开和关闭时间戳之间检测到的总时间电压。查询应该类似于 SELECT (get times) FROM tableA WHERE OnTime >= @sometime AND O
SELECT (get times) FROM tableA WHERE OnTime >= @sometime AND OffTime <= @Sometime.
其中Id、ontime和Offtime是列
理想的结果是总时间为120分钟您可以使用老式的方式组合一对行:
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
或使用该函数(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 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
或使用该函数(SQL Server 2012或更高版本):
如果您的条目始终与其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
如果您想尝试以下示例,我在这里为您做了一个尝试:如果您的条目始终与其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
如果你想试试这个例子,我在这里给你做了一把小提琴:考虑桌子
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
然而,您的设计是相当不幸的,因为它需要记录
严格按顺序进行。我强烈建议将这两个日期时间保存在同一条记录中考虑表
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
然而,您的设计是相当不幸的,因为它需要记录
严格按顺序进行。我强烈建议将两个日期时间保存在同一条记录中以下代码将对您有所帮助
;WITH tblDateDifference AS
(
SELECT ROW_NUMBER() OVER(ORDER BY ID) AS RowNumber, OnTime,OffTime
FROM tableA
)
SELECT sum(DATEDIFF(MINUTE,cur.OnTime,nxt.OffTime)) AS TotalMinute
FROM tblDateDifference cur,tblDateDifference nxt
WHERE nxt.RowNumber = cur.RowNumber + 1
单击此处:以下代码将对您有所帮助
;WITH tblDateDifference AS
(
SELECT ROW_NUMBER() OVER(ORDER BY ID) AS RowNumber, OnTime,OffTime
FROM tableA
)
SELECT sum(DATEDIFF(MINUTE,cur.OnTime,nxt.OffTime)) AS TotalMinute
FROM tblDateDifference cur,tblDateDifference nxt
WHERE nxt.RowNumber = cur.RowNumber + 1
单击此处:编辑您的问题,并(1)提供适当的数据库标签;(2) 提供示例数据和所需结果。“我不确定如何以这种方式求和多个datediff()。”不确定什么?你试过了吗?出什么问题了?这是SQL Server,对吗?编辑标记并添加数据库服务器(和版本)。@下划线\u我不确定如何获取多行之间的日期差异,然后将这些差异相加。每行将有一个ON TIME或OFF TIME。在使用where子句运行报告时,我需要将这些差异之间的所有时间相加。编辑问题的可能重复项和(1)提供适当的数据库标记;(2) 提供示例数据和所需结果。“我不确定如何以这种方式求和多个datediff()。”不确定什么?你试过了吗?出什么问题了?这是SQL Server,对吗?编辑标记并添加数据库服务器(和版本)。@下划线\u我不确定如何获取多行之间的日期差异,然后将这些差异相加。每行将有一个ON TIME或OFF TIME。在使用where子句运行报表时,我需要对这些差异之间的所有时间进行求和。抱歉,我没有读到您的查询的可能重复项--这将起作用,但速度不是很快,因为联接会拉入所有更大的值,这可能是很多值。我喜欢使用lag的第二个方法——这是一个很好的解决方案。很抱歉,我没有读到您的查询——它可以工作,但速度不是很快,因为联接会将所有值都拉大,可能会有很多值。我喜欢使用lag的第二个方法——这是一个很好的解决方案。