You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

SQL Server 2014更新数值时如何避免舍入保留精确值?

解决SQL Server中除法舍入问题,获取精确数值的方法

嘿,这个问题我之前也踩过坑!核心问题出在SQL Server的除法运算规则和数值类型的精度处理上,咱们一步步来搞定它:

先搞清楚为啥会出现6.00而非6.6

你遇到的舍入主要有两个可能的原因:

  • 整数除法的陷阱:如果[Avg Time to Dispatch in Minutes]是整数类型(比如intsmallint),用它除以整数60时,SQL Server会执行整数除法——直接丢弃小数部分,只保留整数结果。比如396分钟除以60本来是6.6,但整数除法会得到6,赋值到numeric(13,4)列后就变成6.0000了。
  • 数值精度的隐式处理:就算分钟列是numeric类型,SQL Server的数值运算精度规则也可能导致结果被自动舍入,不过你的列是4位小数,6.6是一位,这个情况大概率是整数除法导致的。

具体解决方案

1. 强制执行浮点除法(最直接的办法)

只要把除数或被除数转为带小数的类型,就能让SQL Server放弃整数除法,计算精确的小数结果。比如:

UPDATE TempTable1 
SET [Avg Time to Dispatch in Hours] = [Avg Time to Dispatch in Minutes] / 60.0

或者显式转换被除数来确保精度:

UPDATE TempTable1 
SET [Avg Time to Dispatch in Hours] = CAST([Avg Time to Dispatch in Minutes] AS DECIMAL(18,6)) / 60

这样396分钟除以60.0就会得到6.6,而不是被截断成6。

2. 提前定义临时表列的高精度(可选)

如果你需要保留更多小数位,比如4位甚至更多,可以在创建临时表的时候就指定更高精度的列,而不是依赖SQL Server自动生成的numeric(13,4)

SELECT 
    Region_Code, 
    '9999999' AS [Avg Time to Dispatch in Minutes], 
    CAST(999999999.9999 AS DECIMAL(18,6)) AS [Avg Time to Dispatch in Hours] 
INTO TempTable1 
FROM table1

这样列的小数位数更充足,能容纳更精确的除法结果,避免后续运算时的隐式舍入。

3. 用ROUND函数控制精度(如果需要固定小数位)

如果你想要主动控制结果的小数位数(比如保留1位得到6.6),可以配合ROUND函数:

UPDATE TempTable1 
SET [Avg Time to Dispatch in Hours] = ROUND([Avg Time to Dispatch in Minutes] / 60.0, 1)

这个方法是主动调整精度,适合需要固定小数位数的场景。

快速验证问题

你可以先跑个测试查询,直观看到两种除法的区别:

SELECT 
    [Avg Time to Dispatch in Minutes],
    [Avg Time to Dispatch in Minutes] / 60 AS 整数除法结果,
    [Avg Time to Dispatch in Minutes] / 60.0 AS 浮点除法结果
FROM TempTable1

这样就能确认是不是整数除法在搞鬼啦。

内容的提问来源于stack exchange,提问作者PurpleRugz

火山引擎 最新活动