Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL在更大的时间跨度内计算多个时间差_Sql_Sql Server_Date_Datetime_Sql Server 2017 - Fatal编程技术网

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

我有一个sql后端和一个跟踪两个日期列的表。这两列分别称为On Time和OffTime。列的格式为小日期时间。该表由arduino微控制器和附带的VB表单应用程序填充,当检测到电压时,该应用程序将在OnTime列中插入一个日期,当电压消除时,填充一个OffTime日期。我需要编写一个sql查询,它可以收集在每个打开和关闭时间戳之间检测到的总时间电压。查询应该类似于

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的第二个方法——这是一个很好的解决方案。