为什么SUM将我的表达式转换为不太精确的表达式?

时间:2013-12-03 15:13:58

标签: sql-server tsql sql-server-2012

考虑以下两个问题:

SELECT 
SUM(val)/convert(decimal(38),42) b
FROM (SELECT 62.13 val) t 

SELECT 
val/convert(decimal(38),42) b
FROM (SELECT 62.13 val) t 

结果

1.479285

1.479285714285714285714285714285714285

分别

http://msdn.microsoft.com/en-us/library/ms187810(v=sql.110).aspx的文档说第一个表达式应该是小数(38,s)不应该吗?

3 个答案:

答案 0 :(得分:4)

是的,对于第一个查询的第一个部分,我们得到decimal(38,s)(在这种情况下,s将为2)。但是我们有一个分区 - 所以我们需要考虑在division occurs

时精度和比例会发生什么

操作:

  

e1 / e2

精度:

  

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

规模:

  

max(6,s1 + p2 + 1)

因此除法的结果,我们得到38 - 0 + 2 + max(6,2 + 38 + 1)= 81. 81!的精度。并且比例将是最大值(6,2 + 38 + 1)= 39.但是你不能有decimal(81,39)。所以我们有:

  

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

答案 1 :(得分:1)

SUM尊重val的数据类型,而不像您似乎正在寻找的DECIMAL(38,36)。如果使用CONVERT在生成它的子语句中显式设置val的数据类型,它将由SUM继承。即:

SELECT 
SUM(val)/convert(decimal(38),42) b
FROM (SELECT CONVERT(DECIMAL(38,36), 62.13) val) t

或者您可以将足够重要的零(其中34个,或“62.130000000000000000000000000000000000”)添加到文字的末尾,以向TSQL演示您在数据类型中关注的点右边有多少有效数字。

答案 2 :(得分:0)

第二个查询解释了这个:

DECLARE @what sql_variant

SELECT @what = 62.13
SELECT
    SQL_VARIANT_PROPERTY(@what, 'BaseType'),
    SQL_VARIANT_PROPERTY(@what, 'Precision'),
    SQL_VARIANT_PROPERTY(@what, 'Scale')

SELECT @what = SUM(62.13)
SELECT
    SQL_VARIANT_PROPERTY(@what, 'BaseType'),
    SQL_VARIANT_PROPERTY(@what, 'Precision'),
    SQL_VARIANT_PROPERTY(@what, 'Scale')

SELECT @what = SUM(val)/convert(decimal(38),42) FROM (SELECT 62.13 val) t
SELECT
    SQL_VARIANT_PROPERTY(@what, 'BaseType'),
    SQL_VARIANT_PROPERTY(@what, 'Precision'),
    SQL_VARIANT_PROPERTY(@what, 'Scale')

SELECT @what = val/convert(decimal(38),42) FROM (SELECT 62.13 val) t 
SELECT
    SQL_VARIANT_PROPERTY(@what, 'BaseType'),
    SQL_VARIANT_PROPERTY(@what, 'Precision'),
    SQL_VARIANT_PROPERTY(@what, 'Scale')