SQL Server总值的持续时间

时间:2017-11-30 14:47:36

标签: sql sql-server

我正在处理包含以下内容的表格(以下示例):

Device varchar(90)  Value varchar(1000)  Date_time datetime2(7)
---------------------------------------------------------------
device1                  10              2017-30-11 13:55
device1                  50              2017-30-11 14:00
device1                 100              2017-30-11 14:45
device1                  50              2017-30-11 14:55

目前每次更新值列时都会更新date_time列。

上面只是一个例子 - 这张表要大得多。

我想要实现的是返回过去7天的表格,显示device1的值为10,值为50等等的总持续时间 - 我不确定我的数据是否可行。

编辑:我想要实现的是:

Device           Value         Last_seven_days
--------------------------------------------------
device1            10          5 hours
device1            50          5 hours 10 minutes
device1           100          3 hours 5 minutes

如何显示时间并不重要 - 只要它包括时间和时间。分钟

2 个答案:

答案 0 :(得分:1)

您可以使用lead()获取下一个日期/时间:

select t.*,
       lead(date_time, 1, getdate()) over (partition by device order by date_time) as next_date_time
from t;

然后,你假设" 7天"基于date_time,您可以进行一些过滤和聚合:

select device1, value,
       sum(datediff(second, date_time, next_date_time)) as duration_in_seconds
from (select t.*,
             lead(date_time, 1, getdate()) over (partition by device order by date_time) as next_date_time
      from t
     ) t
where date_time >= dateadd(day, -7, cast(getdate() as date))
group by device1, value;

答案 1 :(得分:0)

这应该考虑到开始时间之前的时间段。我提供了一个测试表来帮助验证时间。

DECLARE @testtable TABLE (Device varchar(90), [Value] varchar(1000), Date_time datetime2(7))
INSERT INTO @testtable VALUES
 ('device1', '10', '2017-11-29 13:55:00')
,('device1', '50', '2017-11-29 14:00:00')
,('device1', '100', '2017-11-29 14:45:00')
,('device1', '50', '2017-11-29 14:55:00')
,('device2', '20', '2017-11-20 02:45:00')
,('device2', '23', '2017-11-23 00:00:02')
,('device3', '03', '2016-01-01 00:00:00')
,('device3', '04', '2016-10-03 03:59:00')

DECLARE @startdate datetime = '2017-11-23 00:00:00'
       ,@enddate   datetime = '2017-11-30 00:00:00'

SELECT dT.Device
      ,dT.Value
      ,RIGHT('0' + CAST(DATEDIFF(second, CASE WHEN @startdate > dT.Date_time
                                               THEN @startdate
                                               ELSE dT.Date_time
                                         END, dT.endtime) / 3600 AS VARCHAR),3) + ':' + 
       RIGHT('0' + CAST((DATEDIFF(second, CASE WHEN @startdate > dT.Date_time
                                                THEN @startdate
                                                ELSE dT.Date_time
                                          END, dT.endtime) / 60) % 60 AS VARCHAR),2) + ':' +
       RIGHT('0' + CAST(DATEDIFF(second, CASE WHEN @startdate > dT.Date_time
                                               THEN @startdate
                                               ELSE dT.Date_time
                                         END, dT.endtime) % 60 AS VARCHAR),2) AS [Time Passed]
  FROM (
        SELECT *
               --is null when the last status has been reached for a device
              ,COALESCE((SELECT MIN(Date_time) 
                           FROM @testtable T2 
                          WHERE T2.Device = T1.Device AND T2.Value <> T1.Value
                                AND T2.Date_time > T1.Date_time     
                        ), @enddate ) AS endtime
          FROM @testtable T1
       ) AS dT
WHERE dT.EndTime > @startdate   

制作:

Device   Value  Time Passed
device1  10     00:05:00
device1  50     00:45:00
device1  100    00:10:00
device1  50     09:05:00
device2  20     00:00:02
device2  23     167:59:58
device3  04     168:00:00