Lassen Sie mich die offensichtliche Faust sagen: Ich verstehe vollkommen, dass Gleitkommatypen Dezimalwerte nicht genau darstellen können . Hier geht es nicht darum! Dennoch sind Fließkommaberechnungen soll deterministisch sein .
Nun, da dies nicht im Weg ist, möchte ich Ihnen den merkwürdigen Fall zeigen, den ich heute beobachtet habe. Ich habe eine Liste von Gleitkommawerten und möchte sie zusammenfassen:
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
So weit, so gut - keine Überraschungen hier. Wir alle wissen, dass 1.2
dies nicht genau in binärer Darstellung dargestellt werden kann, daher wird das "ungenaue" Ergebnis erwartet.
Nun passiert Folgendes Seltsames, wenn ich mich einer anderen Tabelle anschließe:
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 Geige , Sie können dort auch den Ausführungsplan sehen)
Ich habe die gleiche Summe über die gleichen Werte, aber einen anderen Gleitkommafehler. Wenn ich der Tabelle weitere Zeilen hinzufüge #A
, können wir sehen, dass der Wert zwischen diesen beiden Werten wechselt. Ich konnte dieses Problem nur mit a reproduzieren LEFT JOIN
; INNER JOIN
funktioniert hier wie erwartet.
Dies ist unbequem, weil es bedeutet , dass ein DISTINCT
, GROUP BY
oder PIVOT
sieht sie als unterschiedliche Werte (was eigentlich ist , wie wir dieses Problem entdeckt).
Die offensichtliche Lösung besteht darin, den Wert zu runden, aber ich bin neugierig: Gibt es eine logische Erklärung für dieses Verhalten?