当我执行这个SQL
时SELECT 1.4 UNION ALL
SELECT 2.0400 union all
SELECT 1.24
我得到以下结果:
1.4000
2.0400
1.2400
但是当我执行以下SQL
时SELECT sum(1.4) UNION ALL
SELECT sum(2.0400) union all
SELECT sum(1.24)
我得到以下结果:
1.4
2.0
1.2
为什么所有记录的精确度(比例)都有差异? 它不应该总是使用没有数据丢失的精度,就像第一个sql一样吗?
THX。
答案 0 :(得分:3)
我知道这是一个很老的问题,但现有的答案似乎都没有解决“为什么?”问题的一个方面。
首先,文字表达式的数据类型是什么?我不确定(并且没有查找)所以我运行了以下内容:
select 1.4 union all
select 'frob'
返回错误:
Msg 8114,Level 16,State 5,Line 1
将数据类型varchar转换为数字时出错。
好的,1.4
和其他文字是numeric
- a.k.a decimal
。
接下来,如果传递decimal(p,s)
1 ,SUM
函数的返回类型是什么:
十进制(38,s)
好的,您的查询中3个SUM
表达式的数据类型为decimal(38,1)
,decimal(38,4)
和decimal(38,2)
。鉴于可供选择的3种数据类型,decimal(38,1)
是最终选择的类型,基于differing precisions and scales的规则。
结果精度和标度的绝对最大值为38.当结果精度大于38时,相应的标度会减小,以防止结果的整数部分被截断。
最后,回到decimal
上的文档:
默认情况下,SQL Server在将数字转换为具有较低精度和比例的小数或数值时使用舍入。但是,如果SET ARITHABORT选项为ON,则SQL Server会在发生溢出时引发错误。仅精度和比例的损失不足以引起错误。
这是你的最终结果。
1 起初这种类型可能看起来很令人惊讶,直到你意识到,sum
通常会对多行进行操作,并且很容易使给定精度和比例的多个值溢出他们自己的数据类型。对于特定 decimal(38,s)
出现,SUM()
为最大可能空间提供容量而不会丢失任何精度,并且意味着可以在查询之前确定最终数据类型已经执行了。
答案 1 :(得分:0)
尝试相同的结果,
SELECT Cast(Sum(1.4) As Numeric(18,4)) UNION ALL
SELECT Cast(Sum(2.0400) As Numeric(18,4)) union all
SELECT Cast(Sum(1.24) As Numeric(18,4))
答案 2 :(得分:0)
试试这个
SELECT sum(1.4)/1.0 UNION ALL
SELECT sum(2.0400)/1.0 union all
SELECT sum(1.24)/1.0
OR
SELECT sum(1.4)/1.0 UNION ALL
SELECT sum(2.0400) union all
SELECT sum(1.24)
答案 3 :(得分:0)
普通查询传递字符串值否则使用sum或decimal它是字符串转换为指定格式这是事实
SELECT sum(convert(decimal,1.4,3)) UNION ALL
SELECT sum(2.0400) union all
SELECT sum(1.24)
答案 4 :(得分:0)
尝试此查询
SELECT convert(decimal(18,4),Sum(1.4)) UNION ALL
SELECT convert(decimal(18,4),Sum(2.0400)) UNION ALL
SELECT convert(decimal(18,4),Sum(1.24))