TSQL语句根据列出的变量的顺序返回不同的值

时间:2018-02-02 19:13:34

标签: sql-server tsql rounding

以下TSQL语句根据@Size和@ Value的顺序返回不同的值。第一个语句返回1687.500000但第二个语句返回1687.600000。 我猜它是因为一些四舍五入但我无法弄清楚自己。任何帮助都会非常感激。

DECLARE @Amount DECIMAL(20,4) = 2,
@PriceDiff DECIMAL(25,10) = 0.421875,
@Size DECIMAL(16,4)= 200000.0000,
@Value DECIMAL(25,15)= 0.010000000000000

SELECT  @Amount * @PriceDiff * @Size * @Value   AS FinalValue 

SELECT  @Amount * @PriceDiff *  @Value * @Size   AS FinalValue

From Management studio

1 个答案:

答案 0 :(得分:5)

您遇到舍入错误的原因是SQL Server确定Decimal类型的精度和比例的乘法结果的方式。 see here

此外,SQL Server对相同/等优先运算符的操作顺序为LTR

鉴于第一步是多个@Amount * @PriceDiff。根据该链接,精度和规模将是:

 precision = 20 + 25 + 1 = 46
 scale = 4 + 10 = 14
 resulting data type = Decimal(46, 14)

这个结果超过了Decimal的最大允许精度,所以事情变得有点粘。在该链接的底部,您将看到:

  
      
  • 结果精度和比例的绝对最大值为38.当结果精度大于38时,相应的比例会减小,以防止结果的整数部分被截断。
  •   

Reading up on this further你会发现,而不只是删掉所有的小数位来制作一个Decimal(38,0)或者允许所有精度为十进制的Decimal(38,38) SQL服务器猜猜并使它成为Decimal(38,6)

一切都很好,但到目前为止我们的结果是0.84375,并且适合我们新的Decimal(38,6)容器。

您现在可以看到,如果我们将此乘以@Size,我们仍然会在Decimal(38,6)的限制范围内,结果为168750。因此,即使使用精度和比例数学,我们仍然很好,并且得到的舍入将达到6的标准。

但是,如果我们将0.84375结果和@Value precision = 38 + 25 + 1 = 64 scale = 6 + 15 = 21 result = Decimal(64, 21) 取得结果,我们就会得到:

0.0084375

这意味着我们又强制将其强制为十进制(38,6)......并且0.08438不适合,因此它会四舍五入为"eb init"