让我指出一个明显的拳头:我完全理解浮点类型不能准确表示十进制值。这不是这个!但是,浮点计算应该是确定性的。
既然已经解决了,让我向您展示我今天观察到的奇怪案例。我有一个浮点值列表,我想总结一下:
CREATE TABLE #someFloats (val float);
INSERT INTO #someFloats (val) VALUES (1), (1), (1.2), (1.2), (1.2), (3), (5);
SELECT STR(SUM(#someFloats.val), 30, 15) FROM #someFloats;
DROP TABLE #someFloats;
-- yields:
-- 13.600000000000001
到目前为止,一切都很好-这里不足为奇。我们都知道1.2
不能完全用二进制表示形式,因此期望“不精确”的结果。
现在,当我左联接另一个表时,会发生以下奇怪的事情:
CREATE TABLE #A (a int);
INSERT INTO #A (a) VALUES (1), (2);
CREATE TABLE #someFloats (val float);
INSERT INTO #someFloats (val) VALUES (1), (1), (1.2), (1.2), (1.2), (3), (5);
SELECT #A.a, STR(SUM(#someFloats.val), 30, 15)
FROM #someFloats LEFT JOIN #A ON 1 = 1
GROUP BY #A.a;
DROP TABLE #someFloats;
DROP TABLE #A;
-- yields
-- 1 13.600000000000001
-- 2 13.599999999999998
(sql fiddle,您也可以在那里查看执行计划)
我也有同样的比之和相同的价值观,但不同的浮点错误。如果我向table添加更多行#A
,我们可以看到该值在这两个值之间交替。我只能用来重现此问题LEFT JOIN
;INNER JOIN
在这里按预期工作。
这是不方便的,因为这意味着一个DISTINCT
,GROUP BY
或PIVOT
将其视为不同的值(这实际上是我们发现了这个问题)。
显而易见的解决方案是舍入该值,但我很好奇:这种行为是否存在逻辑解释?