计算同一张表中SQL中两个时间戳的差值

Posted

技术标签:

【中文标题】计算同一张表中SQL中两个时间戳的差值【英文标题】:Calculate difference between two timestamps in SQL in the same table 【发布时间】:2016-01-01 15:49:40 【问题描述】:

我有一个表格,列是:

ID   UserId Serial ModifiedDate
---- ------ ----- ----------------

我需要计算每行时间戳之间的差异。例如,如果我有这样的表:

ID   UserId Serial ModifiedDate
---- ------ ----- ----------------
001    1     1111  2015-07-20 10:56:53.0000000
002    1     1111  2015-07-21 18:49:24.0000000
003    1     1111  2015-07-22 08:49:23.0000000

我需要区分 001 和 002 的时间戳,然后是 002 和 003 的时间戳,结果需要如下:

ID   UserId Serial ModifiedDate                Difference 
---- ------ ----- ----------------             --------
001    1     1111  2015-07-20 10:56:53.0000000 
002    1     1111  2015-07-21 18:49:24.0000000
003    1     1111  2015-07-22 08:49:23.0000000

我尝试使用游标来执行此操作,但我找不到在新别名列中获取差异结果的方法。

这是我的查询:

DECLARE @id bigint, @lastmodif datetime2(7), @id2 bigint, @lastmodif2 datetime2(7),@total int;

DECLARE status_cursor CURSOR FOR 

SELECT [Id], [ModifiedDate], '0' AS Difference 
FROM [Registrations]
  where p.Serial = 1111  
  Order by ModifiedDate

OPEN status_cursor

DECLARE status_cursor2 CURSOR FOR 

SELECT [Id], [ModifiedDate],'0' AS Difference 
FROM [Registrations]
  where p.Serial = 1111  
  Order by ModifiedDate

OPEN status_cursor2

FETCH NEXT FROM status_cursor2

WHILE @@FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM status_cursor INTO @regid, @lastmodif
FETCH NEXT FROM status_cursor2 INTO @regid2, @lastmodif2
SET @total = 
        (
           DATEDIFF(second,@lastmodif,@lastmodif2)
        )
UPDATE status_cursor SET Result = @total

【问题讨论】:

什么版本的sql server? 版本为2012 11.0.5532.0 我尝试使用 LEAD 但我收到此消息:未启用并行数据仓库 (PDW) 功能 @juanfandres :在我的回答中检查替代解决方案。 【参考方案1】:

这适用于 2008 年和更大的返回时间差异(以秒为单位)。

 WITH cte AS (SELECT ID, ModifiedDate, 
   DENSE_RANK() OVER (ORDER BY ID ASC) AS Ranking from Registrations),

 SELECT cte1.ID, cte1.ModifiedDate, 
   DATEDIFF(ss, cte1.ModifiedDate, cte2.ModifiedDate) AS TimeDiff 
   FROM cte cte1, cte cte2 
   WHERE cte1.Ranking = cte2.Ranking - 1

【讨论】:

【参考方案2】:

根据您的评论,您的 SQL Server 版本是 2012。所以您可以通过 LEAD() 执行此操作

您需要将HH 替换为所需的值

SELECT ID,
       UserId,
       Serial,
       ModifiedDate,
       DATEDIFF(HH,ModifiedDate,LEAD(ModifiedDate) over(ORDER BY ID)) AS [Difference]
FROM Times

如果 LAG() 由于配置问题而无法在您的数据库上运行,请尝试以下查询。

WITH CTE AS
(
    SELECT *,ROW_NUMBER() OVER(ORDER BY CAST(ID AS INT)) AS RN
    FROM times
)

SELECT C1.*,DATEDIFF(HH,C1.MODIFIEDDATE,C2.MODIFIEDDATE) AS [DIFFERENCE]
FROM CTE C1 LEFT JOIN CTE C2 ON C1.RN+1 = C2.RN

【讨论】:

他做到了。因为我问了! ;) 我尝试使用 LEAD 但我收到此消息:未启用并行数据仓库 (PDW) 功能。 数据库兼容级别?【参考方案3】:

适用于 sql server 2008 及更高版本

with cte as 
(
    select 1 as Id , 1 as UserID, 1111 as Serial, ' 2015-07-20 10:56:53.0000000' as ModifiedDate
    union all 
    select 
    002,    1,     1111 , '2015-07-21 18:49:24.0000000'
    union all
    select 
    003,    1,     1111,  '2015-07-22 08:49:23.0000000'
)
,
cte2 as (
select *, 
        (select min(ModifiedDate) from cte as nextRow where nextRow.Serial = cte.Serial and nextRow.Id > cte.Id)  as NextModifiedDate

    from 
    cte 
)
select id,USERid,Serial,ModifiedDate,DATEDIFF(SECOND,ModifiedDate,isnull(NextModifiedDate,ModifiedDate)) as Difference 
 from cte2

另外,你可以直接在你的桌子上使用它

    select * 
            -- ,(select min(ModifiedDate) from Registrations as nextRow where nextRow.Serial = Registrations.Serial and nextRow.Id > Registrations.Id)  as NextModifiedDate
            , DATEDIFF(second,Registrations.ModifiedDate, 
                        isnull((select min(ModifiedDate) from Registrations as nextRow where nextRow.Serial = Registrations.Serial and nextRow.Id > Registrations.Id),Registrations.ModifiedDate)
                       ) as Difference 
        from 
        Registrations 

【讨论】:

另外,您可以使用此 select * -- ,(select min(ModifiedDate) from Registrations as nextRow where nextRow.Serial = Registrations.Serial and nextRow.Id > Registrations.Id) as NextModifiedDate , DATEDIFF (second,Registrations.ModifiedDate, isnull((select min(ModifiedDate) from Registrations as nextRow where nextRow.Serial = Registrations.Serial and nextRow.Id > Registrations.Id),Registrations.ModifiedDate) ) 作为与Registrations的区别 我尝试直接在表中使用查询,但是当我在 2 个时间戳之间存在差异时,如下所示:2015-07-22 08:49:23.0000000 - 2015-07-22 08:50: 08.0000000 我有负差,不代表这个数字 我用负差解决了这个问题。现在,当我有 2 个等于时间戳时,我遇到了问题。在差异列中,我有相同的数字。例如:我有这 3 行 2015-07-26 22:42:03.0000000 / 2015-07-26 22:42:03.0000000 / 2015-07-27 07:07:16.0000000。如您所见,前 2 个相等,因此在差异列中,前 2 个相同的数字是第 2 个和第 3 个之间的差异。

以上是关于计算同一张表中SQL中两个时间戳的差值的主要内容,如果未能解决你的问题,请参考以下文章

sql怎么计算时间差

用于从表中选择具有最新时间戳的行的 JOOQ 代码

带有在单独表中定义的时间戳的 SQL EXCLUDE 记录

InfluxDB 和 Grafana:在同一图形面板上比较两个具有不同时间戳的数据库

如何根据时间戳耦合同一张表中的数据点?

计算两个时间戳之间的差异并获得 unix 时间戳的差异