自动十进制舍入问题


11

这个问题相对简单。我需要计算3列,中间结果是很大的小数,并且SQL Server早就遇到了一个问题,即无论是否进行任何类型的转换,SQL Server基本上都会舍入小数。

例如,让我们做一个简单的除法1234/1233。计算器将产生1,00081103000811。但是,当我在SQL Server上执行此操作时,我们得到以下信息:

-- Result: rounded at 1.000811000... with trailing zeroes up until the 37 precision
SELECT CAST(CAST(1234 AS DEC(38,34))/CAST(1233 AS DEC(38,34)) AS DEC(38,37))

-- Result: rounded at 1.000811
SELECT CONVERT(DECIMAL(38,32), 1234)/CONVERT(DECIMAL(38,32),1233)

-- Correct result at 1,00081103000811
-- But this requires the zeroes to be put in manually when you don't
-- even know the precision of the end result
SELECT 1234.0/1233.00000000000000

为什么会发生这种自动舍入?当您不确定某个数字(int或dec的一部分)将有多大时,由于表格中可能包含各种不同的值,因此计算疯狂的长十进制值的最佳方法是什么?

谢谢!

Answers:


17

tl; dr

不要用SQL语言进行计算

长一点

在MSDN上很好地定义结果的规模和精度。确实,这不是直观的。但是,简单来说,当输入比例很高时,精度会损失,因为需要将结果比例降低到38,并降低精度。

确认事情

  • 第一个示例中的额外CAST只需添加零
  • 截断按照我的MSDN链接发生(第二个示例)
  • 带有常量的第三个示例隐含了十进制值,这些值正好足够(5,1)和18,14)。
    这意味着结果小数位数和精度没有截断(请参见打击)

有关第一种和第三种情况的更多信息。

除法的结果标度为max(6, s1 + p2 + 1)

  • 第一个例子,这是77下降到38,精密类似地被迫下降,但最低的6(参照
  • 第三个例子是24,因此精度不需要调整

你有一些选择

  • 在客户端代码中计算,例如.net
  • 使用CLR函数进行.net计算
  • 失去准确性
  • 使用float并以15位有效数字作为最佳选择

最后,请参见SO /programming/423925/t-sql-decimal-division-accuracy/424052#424052


1

不知道这是否有帮助,但对我来说,我的临时表列设置为十进制,我是将插入的convert(decimal(15,2),0.65)传递给temp_table。这是自动舍入,我将列类型更改为十进制(16,2)以匹配所传递的内容。表现在存储0.65。


1

我不得不做个工作。这是我所做的:

-----------------------------------
DECLARE @DENIED INT  = 33443
DECLARE @PAID INT = 148353
DECLARE @PCT Decimal (6,2)

SET @PCT = (@DENIED * 100.00 / @PAID)  -- Instead of dividing by 100, I included decimals

SELECT
@DENIED AS DEN
,@PAID AS PAID
,@PCT AS PCT

结果:

DEN PAID    PCT
-----   ----    -----
33443   148353  22.54   -- Instead of 22.00

希望这可以帮助。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.