Sql server SQL—然后截断小数时的大小写

Sql server SQL—然后截断小数时的大小写,sql-server,Sql Server,下面带有CASE WHEN的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的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
CASE表达式必须生成具有特定数据类型的结果。该数据类型在编译CASE表达式时确定,并从所有THEN子句和任何ELSE子句的数据类型派生

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


确定每个WHEN表达式的数据类型的确切规则可在以下文档中找到。

这是预期行为,与CASE-WHEN构造几乎无关:

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

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


**e1{UNION |除了| INTERSECT}e2

您可以使用round函数:

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

尝试使用浮点。@KeithJohnHutchison:浮点不精确。@KeithJohnHutchison问题是为什么会发生这种情况?顺便说一句:浮动是——在大多数情况下——应该避免的事情……为什么这会降低投票率呢?MSDN链接中回答这个问题的摘录是:如果大于6,如果积分部分大于32,则刻度将设置为6。在这种情况下,积分部分和比例都将减少,结果类型为小数38,6。结果可能会四舍五入到小数点后6位,或者如果整数部分不能放入32位,则会抛出溢出错误。当您将精度和比例相乘时,会添加精度和比例,因此当您执行将进一步改变它们的除法运算时,它们太大,因此您的比例会被截断为6。虽然MSDN链接中的信息确实有助于回答此问题,但您在此处编写的信息具有误导性。你写的案例3的规模是最有限的,因此这就是为什么要使用它。这是错误的。给定相同的积分部分,将始终使用更高的比例,但是在本例中,情况3的计算积分部分不同。在OP的示例中,使用案例3的比例是因为它产生了允许的最大精度38和最大整数部分38-6=32:小数38,6
select round(case when (1 > 0) then @d1 / @d4
    when (2 > 0) then @d2 / @d4
    when (3 > 0) then @d2 / (@d4 * @d3)
end,5)