在 SQL Server 中计算以分钟为单位的时差

Posted

技术标签:

【中文标题】在 SQL Server 中计算以分钟为单位的时差【英文标题】:Calculate time difference in minutes in SQL Server 【发布时间】:2015-01-15 11:50:24 【问题描述】:

我需要两次之间的时间差(以分钟为单位)。我的开始时间和结束时间如下所示:

start time | End Time    
11:15:00   | 13:15:00    
10:45:00   | 18:59:00

我需要第一行的输出为 45,60,15,分别对应于 11:15 和 12:00、12:00 和 13:00、13:00 和 13:15 之间的时间差。

p>

【问题讨论】:

你能发布你想要的输出吗?? 你试过了吗? 我需要第一行数据的输出为 45,60,15。足以将值打印为单独的列。 第二行需要什么输出 对于第二行,我需要输出为 15、60、60、60、60、60、60、59 【参考方案1】:

使用DateDiff 有MINUTE 差异:

SELECT DATEDIFF(MINUTE, '11:10:10' , '11:20:00') AS MinuteDiff

可能对您有帮助的查询:

SELECT StartTime, EndTime, DATEDIFF(MINUTE, StartTime , EndTime) AS MinuteDiff 
FROM TableName

【讨论】:

Incorrect parameter count in the call to native function 'DATEDIFF' 根据 MariaDB 的文档,DATEDIFF 只需要两个参数: @TarangP 问题与 SQL Server 而非 MariaDB 相关【参考方案2】:

试试这个..

select starttime,endtime, case
  when DATEDIFF(minute,starttime,endtime) < 60  then DATEDIFF(minute,starttime,endtime) 
  when DATEDIFF(minute,starttime,endtime) >= 60
  then '60,'+ cast( (cast(DATEDIFF(minute,starttime,endtime) as int )-60) as nvarchar(50) )
end from TestTable123416

您只需要DateDiff..

【讨论】:

【参考方案3】:

以下按预期工作:

SELECT  Diff = CASE DATEDIFF(HOUR, StartTime, EndTime)
                    WHEN 0 THEN CAST(DATEDIFF(MINUTE, StartTime, EndTime) AS VARCHAR(10))
                    ELSE CAST(60 - DATEPART(MINUTE, StartTime) AS VARCHAR(10)) +
                        REPLICATE(',60', DATEDIFF(HOUR, StartTime, EndTime) - 1) + 
                        + ',' + CAST(DATEPART(MINUTE, EndTime) AS VARCHAR(10))
                END
FROM    (VALUES 
            (CAST('11:15' AS TIME), CAST('13:15' AS TIME)),
            (CAST('10:45' AS TIME), CAST('18:59' AS TIME)),
            (CAST('10:45' AS TIME), CAST('11:59' AS TIME))
        ) t (StartTime, EndTime);

要获得 24 列,您可以使用 24 个 case 表达式,例如:

SELECT  [0] = CASE WHEN DATEDIFF(HOUR, StartTime, EndTime) = 0
                        THEN DATEDIFF(MINUTE, StartTime, EndTime)
                    ELSE 60 - DATEPART(MINUTE, StartTime)
                END,
        [1] = CASE WHEN DATEDIFF(HOUR, StartTime, EndTime) = 1 
                        THEN DATEPART(MINUTE, EndTime)
                    WHEN DATEDIFF(HOUR, StartTime, EndTime) > 1 THEN 60
                END,
        [2] = CASE WHEN DATEDIFF(HOUR, StartTime, EndTime) = 2
                        THEN DATEPART(MINUTE, EndTime)
                    WHEN DATEDIFF(HOUR, StartTime, EndTime) > 2 THEN 60
                END -- ETC
FROM    (VALUES 
            (CAST('11:15' AS TIME), CAST('13:15' AS TIME)),
            (CAST('10:45' AS TIME), CAST('18:59' AS TIME)),
            (CAST('10:45' AS TIME), CAST('11:59' AS TIME))
        ) t (StartTime, EndTime);

以下方法也有效,并且可能比一遍又一遍地重复相同的 case 表达式更短:

WITH Numbers (Number) AS
(   SELECT  ROW_NUMBER() OVER(ORDER BY t1.N) - 1
    FROM    (VALUES (1), (1), (1), (1), (1), (1)) AS t1 (N)
            CROSS JOIN (VALUES (1), (1), (1), (1)) AS t2 (N)
), YourData AS
(   SELECT  StartTime, EndTime
    FROM    (VALUES 
                (CAST('11:15' AS TIME), CAST('13:15' AS TIME)),
                (CAST('09:45' AS TIME), CAST('18:59' AS TIME)),
                (CAST('10:45' AS TIME), CAST('11:59' AS TIME))
            ) AS t (StartTime, EndTime)
), PivotData AS
(   SELECT  t.StartTime,
            t.EndTime,
            n.Number,
            MinuteDiff = CASE WHEN n.Number = 0 AND DATEDIFF(HOUR, StartTime, EndTime) = 0 THEN DATEDIFF(MINUTE, StartTime, EndTime)
                                WHEN n.Number = 0 THEN 60 - DATEPART(MINUTE, StartTime)
                                WHEN DATEDIFF(HOUR, t.StartTime, t.EndTime) <= n.Number THEN DATEPART(MINUTE, EndTime)
                                ELSE 60
                            END
    FROM    YourData AS t
            INNER JOIN Numbers AS n
                ON n.Number <= DATEDIFF(HOUR, StartTime, EndTime)
)
SELECT  *
FROM    PivotData AS d
        PIVOT 
        (   MAX(MinuteDiff)
            FOR Number IN 
            (   [0], [1], [2], [3], [4], [5], 
                [6], [7], [8], [9], [10], [11],
                [12], [13], [14], [15], [16], [17], 
                [18], [19], [20], [21], [22], [23]
            ) 
        ) AS pvt;

它通过加入一个包含 24 个数字的表来工作,因此不需要重复 case 表达式,然后使用 PIVOT 将这 24 个数字回滚到列中

【讨论】:

太棒了!!!谢谢。假设如果我需要 24 列,如果不适用,我需要将值设为 0,如何实现? 在极端情况下结果为 null。例如“23:55”、“00:05” @pkExec PIVOT 解决方案有一个小问题,但我认为您所指的“边缘”案例不是边缘案例,只是上述解决方案都不是为了处理结束时间之后的开始时间。 @GarethD 除了它实际上不一定是“之后”。根据实际问题,时间对可以参考例如时间表,表示“Day1-23:55”、“Day2-00:05”。这就是为什么我将其称为边缘情况,这取决于问题。 imo,如果 enddate【参考方案4】:

您可以使用 DATEDIFF(它是一个内置函数)和 %(用于比例计算)和 CONCAT 只将结果生成到一列

select CONCAT('Month: ',MonthDiff,' Days: ' , DayDiff,' Minutes: ',MinuteDiff,' Seconds: ',SecondDiff) as T  from 
(SELECT DATEDIFF(MONTH, '2017-10-15 19:39:47' , '2017-12-31 23:59:59') % 12 as MonthDiff,
        DATEDIFF(DAY, '2017-10-15 19:39:47' , '2017-12-31 23:59:59') % 30 as DayDiff,
        DATEDIFF(HOUR, '2017-10-15 19:39:47' , '2017-12-31 23:59:59') % 24 as HourDiff,
        DATEDIFF(MINUTE, '2017-10-15 19:39:47' , '2017-12-31 23:59:59') % 60 AS MinuteDiff,
        DATEDIFF(SECOND, '2017-10-15 19:39:47' , '2017-12-31 23:59:59') % 60 AS SecondDiff) tbl

【讨论】:

【参考方案5】:

除了 DATEDIFF,您还可以使用 TIMEDIFF 函数或 TIMESTAMPDIFF。

示例

SET @date1 = '2010-10-11 12:15:35', @date2 = '2010-10-10 00:00:00';

SELECT 
TIMEDIFF(@date1, @date2) AS 'TIMEDIFF',
TIMESTAMPDIFF(hour, @date1, @date2) AS 'Hours',
TIMESTAMPDIFF(minute, @date1, @date2) AS 'Minutes',
TIMESTAMPDIFF(second, @date1, @date2) AS 'Seconds';

结果

TIMEDIFF : 36:15:35
Hours : -36
Minutes : -2175
Seconds : -130535

【讨论】:

【参考方案6】:

请尝试以下方法以获取 hh:mm:ss 格式的时差

从 [TableName] 中选择 StartTime、EndTime、CAST((EndTime - StartTime) as time(0)) 'TotalTime'

【讨论】:

以上是关于在 SQL Server 中计算以分钟为单位的时差的主要内容,如果未能解决你的问题,请参考以下文章

如何在PHP中以分钟为单位获取时差

如何获得以秒或分钟或小时为单位的时差? [复制]

计算时差,结果以 Seconds.ms (xxxx.xxx) 为单位

如何获取两个日期时间字段的轨道分钟时差?

如何减去两个 sql 时间戳字段,然后以小时为单位返回时差

mysql中计算两个时间的时间差,以分钟为单位。