sql - HH 中的 DATEDIFF :MM:SS format

标签 sql sql-server sql-server-2008 date datetime

给定一些带有开始时间和结束时间的数据,我需要以小时、分钟、秒和平均长度来计算总长度。

例如,结果必须类似于 45:15:10,表示 45 小时 15 分 10 秒,或 30:07 表示 30 分 07 秒。

我们使用的是 SQL Server 2008 R2,当时间超过 24:59:59 时转换失败。知道我该怎么做吗?

仅供引用,表中的列为 IdStartDateTimeEndDateTime 等。我需要制作一份月度报告,其中包含该月的录音数量、这些记录的总长度以及平均长度。我想知道是否有一种简单的方法来执行所有这些操作。

最佳答案

您不应该转换为 time - 它的目的是存储单个 24 小时时钟上的时间点,而不是持续时间或间隔(即使是本身限制为 < 24 小时,显然你的数据不是)。相反,您可以以所需的最小间隔(在您的情况下为秒)获取 datediff,然后执行一些数学和字符串操作,以您需要的输出格式呈现它(最好将秒返回给应用程序或报告工具并让它完成这项工作)。

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;

结果:

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

这并不完全是您所要求的,因为它不会仅显示 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;

此查询将上述结果中第二行的增量列从 0:22:00 更改为 22:00

关于sql - HH 中的 DATEDIFF :MM:SS format,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14445600/

相关文章:

连接的 SQL 限制

sql - Oracle SQL 中逗号分隔值的总和

c# - 列不允许 DBNull.Value - 没有 KeepNulls - 正确的列映射

mysql - 从主表和关系表中删除重复项?

sql - Postgres : Inner Join with AND condition on same field

json - 用于 json 自动的 sql 服务器。如何获得所有结果

c# - 如何在C#应用程序中进行备份?

sql-server-2008 - 带有 SSRS 2008 参数的 "Select All"

sql - 如何在 SQL-Server 2014 中将表变量传递给存储过程

sql - SQL Server 中基于函数的索引