有时候,当从数据库中选择汇总数据(通常是AVG()
)时,我会得到一个重复的小数,例如:
2.7777777777777777
当我将ROUND(AVG(x), 2
)应用于该值时,我有时会得到如下结果:
2.7800000000000002
我碰巧知道实际样本有18行SUM(x)
= 50.所以这个命令应该是等价的:
SELECT ROUND(50.0/18, 2)
但是,它会产生预期的结果(2.78)。为什么舍入有时会产生聚合函数的错误结果?
为了验证上述结果,我写了query against a dummy table:
declare @temp table(
x float
)
insert into @temp values (1.0);
insert into @temp values (2.0);
insert into @temp values (1.0);
insert into @temp values (1.0);
insert into @temp values (1.0);
insert into @temp values (1.0);
insert into @temp values (1.0);
insert into @temp values (8.0);
insert into @temp values (9.0);
select round(avg(x), 2),
sum(x),count(*)
from @temp
我知道gotchas of floating point representation,但这个简单的案例似乎不受这些影响。
答案 0 :(得分:3)
十进制数并不总是(甚至通常)将1:1映射到浮点的精确表示。
在您的情况下,双精度浮点可以表示的两个最接近的数字是;
这两个数字之间不存在双精度数,在这种情况下,数据库选择较高的值 - 如您所见 - 舍入为2.7800000000000002。
答案 1 :(得分:2)
你的桌子使用花车。当给定浮点数作为参数时,AVG()
和ROUND()
都会返回浮点数。浮子无法准确表示。当您执行ROUND(50.0/18, 2)
时,您将NUMERIC(8,6)
提供给它DECIMAL(8,6)
。
尝试声明您的列使用更精确的类型,例如DECIMAL(18,9)
。结果应该更加可预测。