HH:MM:SS格式的DATEDIFF

use*_*731 13 sql sql-server datetime date sql-server-2008

我需要根据开始时间和结束时间的一些数据,以小时,分钟,秒和平均长度来计算总长度.

例如,结果必须是45:15:1045小时15分10秒或30:0730分07秒.

SQL Server 2008 R2当时间超过时,我们正在使用并且转换失败了24:59:59.知道如何做到这一点?

有关信息,在表中的列Id,StartDateTime,EndDateTime等我需要让其中包含的记录数月的月度报告中,这些记录的总长度,平均长度.我想知道是否有一种简单的方法来执行所有这些.

Aar*_*and 10

你不应该转换为time- 它意味着在一个24小时的时钟上存储一个时间点,而不是一个持续时间或间隔(即使是一个受限于它自己的时间<24小时,显然你的数据不是这样).相反,你可以在所需的最小间隔(在你的情况下,秒)中取日期,然后执行一些数学和字符串操作,以你需要的输出格式呈现它(也可能最好将秒返回给应用程序或报告工具并让它完成这项工作).

DECLARE @d TABLE
(
  id INT IDENTITY(1,1), 
  StartDateTime DATETIME, 
  EndDateTime DATETIME
);

INSERT @d(StartDateTime, EndDateTime) VALUES 
(DATEADD(DAY, -2, GETDATE()), DATEADD(MINUTE, 15, GETDATE())),
(GETDATE()                  , DATEADD(MINUTE, 22, GETDATE())),
(DATEADD(DAY, -1, GETDATE()), DATEADD(MINUTE,  5, GETDATE())),
(DATEADD(DAY, -4, GETDATE()), DATEADD(SECOND, 14, GETDATE()));

;WITH x AS (SELECT id, StartDateTime, EndDateTime, 
  d = DATEDIFF(SECOND, StartDateTime, EndDateTime),
  a = AVG(DATEDIFF(SECOND, StartDateTime, EndDateTime)) OVER()
  FROM @d
)
SELECT id, StartDateTime, EndDateTime,
  [delta_HH:MM:SS] = CONVERT(VARCHAR(5), d/60/60)
  + ':' + RIGHT('0' + CONVERT(VARCHAR(2), d/60%60), 2)
  + ':' + RIGHT('0' + CONVERT(VARCHAR(2), d % 60), 2),
  [avg_HH:MM:SS] = CONVERT(VARCHAR(5), a/60/60)
  + ':' + RIGHT('0' + CONVERT(VARCHAR(2), a/60%60), 2)
  + ':' + RIGHT('0' + CONVERT(VARCHAR(2), a % 60), 2)
FROM x;
Run Code Online (Sandbox Code Playgroud)

结果:

id  StartDateTime        EndDateTime          delta_HH:MM:SS  avg_HH:MM:SS
--  -------------------  -------------------  --------------  ------------
1   2013-01-19 14:24:46  2013-01-21 14:39:46  48:15:00        42:10:33
2   2013-01-21 14:24:46  2013-01-21 14:46:46   0:22:00        42:10:33
3   2013-01-20 14:24:46  2013-01-21 14:29:46  24:05:00        42:10:33
4   2013-01-17 14:24:46  2013-01-21 14:25:00  96:00:14        42:10:33
Run Code Online (Sandbox Code Playgroud)

这并不是你要求的,因为它不会只显示MM:SS为增量<1小时.您可以使用简单的CASE表达式进行调整:

;WITH x AS (SELECT id, StartDateTime, EndDateTime, 
  d = DATEDIFF(SECOND, StartDateTime, EndDateTime),
  a = AVG(DATEDIFF(SECOND, StartDateTime, EndDateTime)) OVER()
  FROM @d
)
SELECT id, StartDateTime, EndDateTime,
  [delta_HH:MM:SS] = CASE WHEN d >= 3600 THEN 
    CONVERT(VARCHAR(5), d/60/60) + ':' ELSE '' END
  + RIGHT('0' + CONVERT(VARCHAR(2), d/60%60), 2)
  + ':' + RIGHT('0' + CONVERT(VARCHAR(2), d % 60), 2),
  [avg_HH:MM:SS] = CASE WHEN a >= 3600 THEN 
    CONVERT(VARCHAR(5), a/60/60) + ':' ELSE '' END
  + RIGHT('0' + CONVERT(VARCHAR(2), a/60%60), 2)
  + ':' + RIGHT('0' + CONVERT(VARCHAR(2), a % 60), 2)
FROM x;
Run Code Online (Sandbox Code Playgroud)

此查询将上面结果中第2行中的delta列更改0:22:0022:00.


mic*_*czy 5

我稍微修改了 Avinash 的答案,因为如果差异太大,它可能会以错误结束。如果您只需要 HH:mm:ss 就足以在秒级区分任何这样的:

SELECT CONVERT(time, 
  DATEADD(s, 
    DATEDIFF(s, 
      '2018-01-07 09:53:00', 
      '2018-01-07 11:53:01'), 
     CAST('1900-01-01 00:00:00.0000000' as datetime2)
   )
)
Run Code Online (Sandbox Code Playgroud)