使用Sum和case语句时确定Scale。奇怪的结果

时间:2014-02-10 11:44:48

标签: sql-server-2008 tsql sqldatatypes

试图理解为什么我的查询的最终结果是返回小数(18,2)而不是小数(18,3)。

我知道sum将返回十进制(38,s),并且我知道在从case语句返回的结果方面有一些数据类型优先级,但我无法找到有关在case中更改大小的任何文献两个语句都返回带有不同比例的小数

为什么下面的查询返回十进制(38,2)而不是十进制(38,3)?

请注意,我知道如何修复此查询,我更感兴趣的是它为什么不能以当前的形式工作。

感谢。

CREATE TABLE supportContacts 
    (
PolicyNumber char(1),
LoadingRate decimal(18,2),
LoadingRate2 decimal(18,3)
    );

INSERT INTO supportContacts
(PolicyNumber, LoadingRate,LoadingRate2)
VALUES
('A', '15.52', '15.523'),
('B', '18.54', '15.525'),
('C', '1.25', '15.552');

select PolicyNumber
     , case when PolicyNumber = 'A' then sum(loadingrate2)
            else sum(LoadingRate)
            end

     from #supportContacts
group by PolicyNumber

SQL小提琴链接http://sqlfiddle.com/#!3/f4ecd

2 个答案:

答案 0 :(得分:0)

使用像

这样的case语句时,需要显式转换为十进制(18,3)
select PolicyNumber , 
    case when PolicyNumber = 'A' then 
    CAST(sum(loadingrate2) AS DECIMAL(18,3))
    else CAST(sum(loadingrate) AS DECIMAL(18,3))
    end  AS LoadingRate
    from supportContacts
    group by PolicyNumber 

答案 1 :(得分:0)

  

在case语句中,当两者都返回带有不同比例的小数时

不可能。 CASE expression计算一个值。它生成的值的数据类型是通过data type precedence rules确定的,但它可以返回的值必须全部转换为数据类型。

至于为什么它选择(38,2)超过(38,3),好吧,如果它没有足够的可用位,它将始终牺牲比例精度。参见例如Precision, Scale and Length

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

SUM()来电产生的数据类型为decimal(38,2)decimal(38,3)。然后,我们可以使用上述链接中包含的相同规则来确定CASE将要执行的操作以确定其结果类型。要遵循的规则是为e1 { UNION | EXCEPT | INTERSECT } e2操作指定的规则。

结果精确度为max(s1, s2) + max(p1-s1, p2-s2) - max(2,3) + max(38-2, 38-3) - 3 + 3639。如上所述,由于最大精度为38,我们必须减少合成比例。