SQL - CASE WHEN THEN截断小数

时间:2016-12-09 08:17:37

标签: sql-server

以下带有CASE WHEN THEN的sql查询会返回不同的结果。 请注意,精度因原始查询而异,并且案例3已注释。 知道为什么吗?我正在运行SQL Server 2014.

declare @d1 decimal(20, 15), @d2 decimal(20, 15), @d3 decimal(20, 15), @d4 decimal(20, 15)
set @d1 = 22.0
set @d2 = 22.0
set @d3 = 1.00000
set @d4 = 7.0

select
    case when (1 > 0) then @d1 / @d4
        when (2 > 0) then @d2 / @d4
        when (3 > 0) then @d2 / (@d4 * @d3)
    end


--Results:
--Without case 3 commented: 3.142857
--With case 3 commented: 3.142857142857142857

3 个答案:

答案 0 :(得分:4)

CASE 表达式必须生成具有特定数据类型的结果。该数据类型是在编译CASE表达式时确定的,并且是从所有THEN子句和任何ELSE子句的数据类型派生的。

case 3表达式的数据类型的比例低于其他表达式的数据类型,因此当包含它并考虑所有表达式时,结果中的比例尺会更有限。

有关确定每个WHEN表达式数据类型的确切规则,请参阅Precision, Scale and Length下的文档。

答案 1 :(得分:2)

这是预期的行为,并且(几乎)与CASE-WHEN构造无关:https://msdn.microsoft.com/en-us/library/ms190476.aspx

  

操作数表达式表示为表达式e1,精度为p1,比例为s1,表达式为e2,精度为p2,比例为s2。任何非十进制表达式的精度和小数位数是为表达式的数据类型定义的精度和小数位数。

     

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

Operation       Result precision                     Result scale *
e1 + e2         max(s1, s2) + max(p1-s1, p2-s2) + 1  max(s1, s2)
e1 - e2         max(s1, s2) + max(p1-s1, p2-s2) + 1  max(s1, s2)
e1 * e2         p1 + p2 + 1                          s1 + s2
e1 / e2         p1 - s1 + s2 + max(6, s1 + p2 + 1)   max(6, s1 + p2 + 1)
e1 UNION ** e2  max(s1, s2) + max(p1-s1, p2-s2)      max(s1, s2)
e1 % e2         min(p1-s1, p2 -s2) + max( s1,s2 )    max(s1, s2)

** e1 { UNION | EXCEPT | INTERSECT } e2

答案 2 :(得分:0)

你可以使用圆形功能:

select round(case when (1 > 0) then @d1 / @d4
    when (2 > 0) then @d2 / @d4
    when (3 > 0) then @d2 / (@d4 * @d3)
end,5)