create table #t(序号 int,数量 decimal(18,3),单价 decimal(18,4),币制 varchar(10),总价 decimal(18,2))
insert into #t
select 335 ,0.147, 929.6499, '美元' ,136.66 union all
select 335 ,0.073, 929.6499, '美元', 67.87select * from #t
select
(case when 币制 = '日本元' then ceiling(数量*单价)
else cast(ceiling(数量 * 单价 * 100)/100 as dec(18,2))
end)
from #t where 序号 = 335 select
总价 = (case when 币制 = '日本元' then cast(ceiling(数量 * 单价) as dec(18,2))
else cast(ceiling(数量 * 单价 * 100)/100 as dec(18,2))
end)
from #t where 序号 = 335 想达到的结果是等于日本元的时候保留整数,其他的保留2位置小数,
第二条能显示出想要的结果,第一条语句竟然保留了一位小数,求解自己试验了下,case when 中的then后面和else后面,会统一保留为成最长的小数,但是为什么第一句保存了一位

解决方案 »

  1.   

    ceiling的返回类型是intselect                                        
    (case when 币制 = '日本元' then round(数量*单价,0)
    else round(数量 * 单价 ,2)                        
                    end)                        
    from #t where 序号 = 335                                        
      

  2.   

    or try:select                                        
    (case when 币制 = '日本元' then cast(ceiling(数量*单价) as dec(18,2))
    else ceiling(数量 * 单价 * 100.0)/100   
                    end)                        
    from #t where 序号 = 335   
      

  3.   

    表达式的的结果
    的数据类型是由表达式中具有最高优先级的操作数的数据类型决定的
    你的例子中
    不管case 表达式哪个为真
    结果数据类型均为decimal(具有最高优先级的数据类型)
      

  4.   

    无法解释select                                        
    (case when 币制 = '日本元' then ceiling(数量*单价)
    else cast(ceiling(数量 * 单价 * 100)/100 as dec(18,2))                        
                    end)         
    ,ceiling(数量*单价)
    ,数量 * 单价
    ,ceiling(数量 * 单价 * 100)
    ,ceiling(数量 * 单价 * 100)/100
    ,cast(ceiling(数量 * 单价 * 100)/100 as dec(18,2))
    from #t where 序号 = 335                                        
    结果是
    --------------------------------------- --------------------------------------- --------------------------------------- --------------------------------------- --------------------------------------- ---------------------------------------
    136.7                                   137                                     136.6585353                             13666                                   136.660000                              136.66
    67.9                                    68                                      67.8644427                              6787                                    67.870000                               67.87(2 行受影响)
      

  5.   

    select                                        
    总价 = (case when 币制 = N'日本元' then cast(ceiling(数量 * 单价)as dec(18,2))                                        
                    else cast(ceiling((数量 * 单价 * 100)/100 )as dec(18,2))                 
                    end)                        
    from #t where 序号 = 335 select                                        
    总价 = (case when 币制 = '日本元' then cast(ceiling(数量 * 单价) as dec(18,2))                                        
                    else cast(ceiling(数量 * 单价 * 100)/100 as dec(18,2))                        
                    end)                        
    from #t where 序号 = 335    
    --一个括号改变了结果
      

  6.   


    原因在于 decimal 类型字段相乘引发的精度问题,sql为防止整数部分被截断,会自动减小小数位
      

  7.   

    select                                        
    (case when 币制 = '日本元' then ceiling(数量*单价)
    else cast(ceiling(数量 * 单价 * 100/100) as dec(18,2))                        
                    end)                        
    from #t where 序号 = 335   看下括号的位置
    位置不同结果不同
    顺便看看我4#的解释
      

  8.   

    一般sql在dec类型相乘时, 如 dec(p1,s1) * dec(p2,s2) ,
    返回的结果应该是 dec(p,s), 其中p=p1+p2+1, s=s1+s2
    而当p>38时,就会出现小数位的截断,
      据说是以下公式(未验证)
       p=p1-s1+s2+max(6,s1+p2+1)
      s=max(6,s1+p2+1)而这个例子应该是case when ..then dec(p1,s1) else dec(p2,s2) end中,返回结果的精度问题。返回的结果精度应该是  P = max(p1-s1,p2-s2)+ max(s1,s2) , S=max(s1,s2)
    同样当P>38时,S会被截断
      

  9.   


    这个不是因为“乘”截断,一个ceiling一个cast(dec(18,2))本身就要截断。case when是UNION运算:ceiling(数量*单价): dec(37,0)
    cast(dec(18,2)): dec(18,2)dec(37,0) UNION dec(18,2) = dec(38,1)