SQL Server十进制运算不正确

问题描述

当我在sql Server中运行此简单操作时:

Select 800.0 /30.0 

我得到的值是26.666666,即使它四舍五入到6位数字,也应该是26.666667。 如何获得准确的计算结果?我尝试在线搜索它,然后找到了一个解决方案,在该解决方案中,我将每个操作数都转换为高精度的小数,然后再进行操作,但这对我来说并不方便,因为我进行了很多长的复杂计算。认为必须有更好的解决方案。

解决方法

在SQL Server中使用除法时,结果标度之后的任何数字都将被截断,而不是四舍五入。对于您的表达式,您有一个decimal(4,1)和一个decimal(3,1),其结果为decimal(10,6)

Precision = p1 - s1 + s2 + max(6,s1 + p2 + 1)
Scale = max(6,s1 + p2 + 1)

结果,26.66666666666666~被截断为26.666666

您可以通过增加精度和小数位数的大小来解决此问题,然后CONVERT返回所需的精度和小数位数。例如,将decimal(3,1)的精度和小数位数提高到decimal(5,2),然后转换回decimal(10,6)

SELECT CONVERT(decimal(10,6),800.0 / CONVERT(decimal(5,3),30.0));

这将返回26.666667

,

这可能会有所帮助:

使用ROUND (Transact-SQL)

SELECT ROUND(800.0 /30.0,5) AS RoundValue;

结果:

RoundValue

26.666670
,

我认为这是因为SQL Server将您的数字作为decimal值(确切地说,例如6.6666和6.6667表示这些值,而不是6和三分之二)而不是float值(可以使用近似数字)。

如果一开始就明确将其强制转换/转换为float,则应该使计算顺利进行。

下面是一些示例,用以说明intdecimalfloat计算之间的区别

  • 将20除以3
  • 将20除以3,然后再乘以3(数学上应为20)。
SELECT  (20/3)                             AS int_calc,(20/3) * 3                         AS int_calc_x3,(CAST(20 AS decimal(10,3)) /3)     AS dec_calc,3)) /3) * 3 AS dec_calc_x3,(CAST(20 AS float) /3)             AS float_calc,(CAST(20 AS float) /3) * 3         AS float_calc_x3

具有以下结果

int_calc   int_calc_x3   dec_calc   dec_calc_x3   float_calc         float_calc_x3
6         18             6.666666   19.999998     6.66666666666667   20

您可以使用

Select CAST(800.0 AS float) /30.0

结果为26.6666666666667

请注意,如果再乘以30,它将得到正确的结果,例如

Select (CAST(800.0 AS float) /30.0) * 30

结果为800。处理小数的解决方案将没有此结果。

还请注意,一旦将其作为浮点数,则它应保持浮点数,直到以某种方式转换回小数或整数(例如,以int形式保存在表中)。所以...

SELECT A.Num / 30
FROM (Select ((CAST(800.0 AS float) /30.0) * 30) AS Num) AS A

仍将产生26.6666666666667

这将有望帮助您进行长时间的复杂计算。