You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server使用datediff计算时间差获取正确十进制小时值

问题描述

我正在SQL Server中使用datediff函数查询同一张表的两个datetime列,想要得到以小数形式呈现的小时时长结果。

我最初编写的查询语句如下:

Select 
    startdatetime, enddatetime, 
    datediff(minutes, startdatetime, enddatetime) / 60 as 'Hrs worked' 
from table1

得到的结果示例如下:

startdatetime                      |  enddatetime                          |  Hrs. worked
2019-02-28 06:00:00.0000000 -08:00    2019-02-28 07:15:00.0000000 -08:00      1

显然startdatetime和enddatetime的差值应为1.25而非1,请问有没有办法展示1.25这类十进制数值?

我也尝试了如下写法:

Select 
    StartDateTime, EndDateTime, 
    Convert(decimal(3), (Datediff(minute, StartDateTime, EndDateTime))) / 60 AS 'Hrs Worked' 
From Table1

这次确实得到了'1.250000'的时长结果,但我无法去掉末尾的零。如果我将decimal(3)替换为decimal(2),会得到如下报错:

Arithmetic overflow error converting int to data type numeric

请问有什么可行的解决方案?


解决方案

原因分析

  1. 整数除法截断小数:DATEDIFF函数返回值为int类型,两个整数相除时SQL Server默认执行整数除法,会直接舍弃小数部分,因此75分钟/60得到1而非1.25。
  2. decimal参数错误导致溢出:decimal(p,s)的参数中,p为总位数(整数位+小数位之和),s为小数位位数,仅写decimal(2)时默认是decimal(2,0),最多只能存储0~99的整数,若两个时间差超过99分钟,转换时就会触发溢出错误。同时你先转换分钟数再做除法的顺序,会导致最终返回的decimal精度过高,出现多余尾零。

实现方法

方法1:最简写法(自动保留小数)

将除数从60改为60.0,触发浮点除法,无需手动转换类型即可得到带小数的结果:

SELECT 
    startdatetime, enddatetime, 
    DATEDIFF(MINUTE, startdatetime, enddatetime) / 60.0 AS [Hrs worked]
FROM table1
方法2:指定精度去除多余尾零

如果需要固定保留2位小数,直接对除法结果做精度转换即可:

SELECT 
    StartDateTime, EndDateTime, 
    CONVERT(DECIMAL(18,2), DATEDIFF(MINUTE, StartDateTime, EndDateTime) / 60.0) AS [Hrs Worked]
FROM Table1

这里DECIMAL(18,2)表示总位数18位,小数位保留2位,完全覆盖正常业务的时间差范围,不会出现溢出问题,结果直接为1.25不会有多余尾零。

方法3:自动去除尾零(适配展示需求)

如果需要整小时展示为整数、非整小时保留对应小数(如2小时展示为2,1小时15分展示为1.25),可以使用FORMAT函数(SQL Server 2012及以上版本支持):

SELECT 
    startdatetime, enddatetime, 
    FORMAT(DATEDIFF(MINUTE, startdatetime, enddatetime) / 60.0, '0.##') AS [Hrs worked]
FROM table1

内容的提问来源于stack exchange,提问作者R. Pen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 08:06:03