如何在SQL中计算时间

时间:2017-10-06 03:45:22

标签: sql-server tsql time

我的表格看起来像这样

ID              DTTM
123456789   2017-10-05 08:00:00.000
123456789   2017-10-05 08:05:00.000
123456789   2017-10-05 08:07:00.000
123456789   2017-10-05 08:15:00.000
123456789   2017-10-05 08:25:00.000
123456789   2017-10-05 09:00:00.000
123456789   2017-10-05 09:01:00.000
123456789   2017-10-05 09:02:00.000
123456789   2017-10-05 09:03:00.000
123456789   2017-10-05 11:00:00.000

我需要根据时间间隔创建一个标志(日期无关紧要) 它必须是15分钟的间隔才能将标志设置为1 因此,在这种情况下,行1,4,6,10将为标记,此ID的总计将为4 每次如果interval >= 15 minutes它将重新开始直到下一个 我尝试过这样的事情; 使用myLead AS

(
Select        top 100 percent 
            ID,
            DTTM,                
            LEAD(DTTM,1) over (partition by ID order by DTTM) as NextDTTM
From        Example
Order by    ID
), myCount
AS
(
Select      Top 100 percent
            ID,
            DTTM,
            NextDTTM,
            DateDiff("MINUTE",DTTM,NextDTTM) as Interval
from        myLead
)
Select      ID,
            DTTM,
            NextDTTM,
            Interval,
            Case When Interval >= 15 then 1 else 0 END as CountFlag
From        myCount
Where       Interval is not NULL
Order by    ID

但它不能按预期工作?我该如何解决这个问题。

谢谢, Oded Dror

2 个答案:

答案 0 :(得分:0)

如果您使用 MySQL ,则可以尝试使用TIMEDIFF(param1, param2) * param1和param2可以是时间或日期时间值

答案 1 :(得分:0)

我不确定你需要看起来像这样的标志,但使用SQL Server 2012它们是两个棘手的部分。首先,要获得下一行和上一行之间的时间差异:

DECLARE @DataSource TABLE
(
    [ID] BIGINT
   ,[DTTM] DATETIME2
);

INSERT INTO @DataSource ([ID], [DTTM])
VALUES   (123456789, '2017-10-05 08:00:00.000')
        ,(123456789, '2017-10-05 08:05:00.000')
        ,(123456789, '2017-10-05 08:07:00.000')
        ,(123456789, '2017-10-05 08:15:00.000')
        ,(123456789, '2017-10-05 08:25:00.000')
        ,(123456789, '2017-10-05 09:00:00.000')
        ,(123456789, '2017-10-05 09:01:00.000')
        ,(123456789, '2017-10-05 09:02:00.000')
        ,(123456789, '2017-10-05 09:03:00.000')
        ,(123456789, '2017-10-05 11:00:00.000');

SELECT *  
      ,DATEDIFF(MINUTE,CONVERT(TIME, [DTTM]),LEAD(CONVERT(TIME, [DTTM]), 1, NULL) OVER (PARTITION BY [ID] ORDER BY [DTTM])) AS [Minutes]
FROM @DataSource
ORDER BY [DTTM];

enter image description here

然后,我们需要sum从过度间隔的乞讨到当前行的分钟,并将它们分成15

WITH DataSource AS
(
    SELECT *  
          ,DATEDIFF(MINUTE,LAG(CONVERT(TIME, [DTTM]), 1, NULL) OVER (PARTITION BY [ID] ORDER BY [DTTM]), CONVERT(TIME, [DTTM])) AS [Minutes]
    FROM @DataSource
)
SELECT *
      ,SUM(ISNULL([Minutes], 0)) OVER (PARTITION BY [ID] ORDER BY [DTTM] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) / 15 AS [MinutesRank]
FROM DataSource;

enter image description here

有了这个,你可以做任何你需要的事情,因为我们现在每行都有多少分钟。例如:

WITH DataSource AS
(
    SELECT *  
          ,DATEDIFF(MINUTE,LAG(CONVERT(TIME, [DTTM]), 1, NULL) OVER (PARTITION BY [ID] ORDER BY [DTTM]), CONVERT(TIME, [DTTM])) AS [Minutes]
    FROM @DataSource
)
, DataSourceMinutesTotal AS
(
    SELECT *
          ,SUM(ISNULL([Minutes], 0)) OVER (PARTITION BY [ID] ORDER BY [DTTM] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) / 15 AS [MinutesRank]
    FROM DataSource
)
SELECT [ID], [DTTM]
      ,DENSE_RANK() OVER (PARTITION BY [ID] ORDER BY ISNULL([MinutesRank], 0)) AS [IntervalID]
FROM DataSourceMinutesTotal
ORDER BY [DTTM];

enter image description here