decimal和bigint相除时scale是怎么定义的?

How scale is defined when decimal and bigint are divided?

我有 DECIMAL(19,8) 类型的值 A - 小数位数是 8,所以小数点右边存储的小数位数是 8.

现在,我将 A 除以 B,其中 BBIGINT。例如:

SELECT CAST(3 AS DECIMAL(19, 8)) / CAST(27 AS BIGINT)               -- 0.111111111111111111111111111
      ,CAST(300 AS DECIMAL(19, 8)) / CAST(27 AS BIGINT)             -- 11.111111111111111111111111111
      ,CAST(75003 AS DECIMAL(19, 8)) / CAST(13664400 AS BIGINT)     -- 0.005488934750153684025643277

输出值的长度分别为:293029

谁能告诉我为什么三等分的值的长度不是30SQL Server 是如何计算最终结果的比例的?

参数 1:3 AS DECIMAL(19, 8)

参数 2:27 AS DECIMAL (18, 0) -- 默认精度为 18,默认小数位数为 0(BIGINT 由于类型优先级被转换为 DECIMAL

p1 = 19
p2 = 18
s1 = 8
s2 = 0

max precision = (p1 - s1 + s2) + MAX(6, s1 + p2 + 1) -- up to 38

max scale = MAX(6, s1 + p2 + 1)

让我们计算示例 1:

precision: (19 - 8 + 0) + MAX(6, 8 + 18 + 1) = 38
scale:     MAX(6, 8 + 18 + 1) = 27

对于所有示例,您将始终获得最大 27 比例。

 0.111111111111111111111111111 (27)
11.111111111111111111111111111 (27)
 0.005488934750153684025643277 (27)

整个部分只需要必要的数字(1),(2),(1)。

对我来说一切都是完全正确的。

此答案基于 @Paul White from Decimal Truncation In division 的工作。

这是调用数据类型优先级。

当查询在不同但兼容的类型之间执行某些操作时,必须将其中一个转换为另一种类型,无论是显式转换还是隐式转换。

如果你看Data Type Conversion (Database Engine) ,你会看到Decimal和Bigint之间存在隐式转换。

因此您的查询不需要显式转换。

如果您查看 MSDN 上的 Data Type Precedence (Transact-SQL),您将看到:

    1. 十进制
    1. bigint

这意味着decimal比bigint具有更高的优先级,bigint值将转换为decimal。

最后,你的计算将是:

  • 3,000... / 27,000...
  • 300,000... / 27,000...
  • 75003,000... / 27,000...

如果您希望它是 3 / 27,您必须对 Decimal 值进行显式转换。