我正在使用下表编写SQLServer 2008:
id user program seconds
------------------------------------
9999 'user01' 'pr01' 5
列'秒'定义为小数(14,0),表中唯一的行是显示的。
所以我尝试了一些问题:
Q1:
select seconds*0.95 from myTable
union all
select seconds from myTable
它给出了我期望的结果:
4.75
5.00
Q2:
select sum(seconds)*0.95 from myTable
union all
select sum(seconds) from myTable
我期待与Q1相同的结果,但我得到的结果是:
5
5
Q3:
select sum(seconds)*0.95 from myTable
union all
select sum(seconds)*1.00 from myTable
在这种情况下,我得到了我期望的结果:
4.75
5.00
所以,我想知道为什么Q2没有得到预期的结果。 我尝试了相同的例子,'秒'是十进制(2,0)并且工作正常,所以我猜它与小数的大小有关,但在那种情况下,我无法弄清楚为什么Q1和Q3工作,而Q2没有。
答案 0 :(得分:4)
sum(seconds)
的结果是numeric(38,0)
,这是有意义的,因为您可以对任意数量的numeric(14,0)
行进行求和,这样可以避免溢出较小的类型。
将numeric(38,0)
乘以0.95
(numeric(2,2)
)在顶部,根据explanation here得出numeric(38,2)
的结果。
但union
的底部部分为numeric(38,0)
,因此整个结果会转换为numeric(38,0)
,这也是有道理的,因为numeric(38,2)
始终可以转换为{numeric(38,0)
1}}没有错误(尽管小数点后丢失了数字)但是对于非常大的数字,反向投射将不起作用。
您可以将底部显式转换为numeric(38,2)
以避免这种情况。
SELECT sum(seconds) * 0.95 AS S
FROM myTable
UNION ALL
SELECT CAST(sum(seconds) AS NUMERIC(38, 2))
FROM myTable