在转换为十进制的varchar上的聚合不能给出正确的答案

时间:2012-03-07 15:02:54

标签: mysql sql casting

最近我们遇到了一个报告生成问题,其中对varchar值执行了聚合(SUM())。 这些值是存储的工时,它们是整数值,例如:456.9。 由于我们进入维护阶段,因此无法改变表格设计。 经过一些研究后,我通过添加一些显式的转换来修改查询。

select ts.changedto as CHANGEDSTATE,
    cast(sum(coalesce(cast(trim(tw.estimatedhours) AS DECIMAL(5,2)),0)) AS UNSIGNED) as ESTIMATEDHOURS,        
    cast(sum(coalesce(cast(trim(tw.actualhours) AS DECIMAL(5,2)),0)) AS UNSIGNED) as ACTUALHOURS
    from tstatechange ts
                  left outer join tworkitem tw on (ts.workitemkey=tw.workitemkey)
                       left outer join tprojcat pc on (tw.prOJCATKEY = pc.pKEY)
                             where (ts.changedto = '8') and ts.lastedit between '2012-02-01  00:00:00' and '2012-02-28 23:59:59'
                                   and pc.projkey = 39 group by CHANGEDSTATE;

即使此查询返回错误的值。 例如,对于这些值手动求和

(89.35
96
11.15
0
0.1
92
1
609.05
61.25
0.5
1
0.5) 

产生961.9但查询返回963。 任何人都可以帮我解决这个问题。是否有任何特殊功能或任何其他工作?

2 个答案:

答案 0 :(得分:0)

我认为您的查询会受到舍入的影响。那两个0.5可能变成两个1。给你963.你用什么数据库?

答案 1 :(得分:0)

您没有提到您正在使用的SQL服务器,但我不能在MS SQL Server 2008R2上重复此操作。您确定您的查询会返回您列出的数据吗?

select '89.35' as x
into #tmp
union all select '96'
union all select '11.15 '
union all select null 
union all select '0.10 '
union all select '92.00 '
union all select '1.00 '
union all select '609.05'
union all select '61.25 '
union all select '0.50'
union all select '1 '
union all select '0.50 '


select sum(coalesce(cast(ltrim(rtrim(x)) AS DECIMAL(5,2)),0))
from #tmp  -- Yields 961.9

select cast(sum(coalesce(cast(ltrim(rtrim(x)) AS DECIMAL(5,2)),0)) AS INT)
from #tmp  -- Yields 961

select 89.35+96.0+11.15+0.0+0.1+92.0+1.0+609.05+61.25+0.5+1.0+0.5 -- Yields 961.9

SQL Server没有UNSIGNED类型,所以我使用了INT。