Der ANSI-SQL-Standard definiert (Kapitel 6.5, Festlegen der Funktionsspezifikation) das folgende Verhalten für Aggregatfunktionen in leeren Ergebnismengen:
COUNT(...) = 0
AVG(...) = NULL
MIN(...) = NULL
MAX(...) = NULL
SUM(...) = NULL
Die Rückgabe von NULL für AVG, MIN und MAX ist absolut sinnvoll, da der Durchschnitt, das Minimum und das Maximum einer leeren Menge undefiniert sind.
Die letzte, aber ich stört: Mathematisch die Summe von einer leeren Menge wohldefiniert: 0
. Mit 0, dem neutralen Element der Addition, als Basisfall wird alles konsistent:
SUM({}) = 0 = 0
SUM({5}) = 5 = 0 + 5
SUM({5, 3}) = 8 = 0 + 5 + 3
SUM({5, NULL}) = NULL = 0 + 5 + NULL
Wenn Sie "keine Zeilen" SUM({})
als " null
grundsätzlich" definieren, ist dies ein Sonderfall, der nicht zu den anderen passt:
SUM({}) = NULL = NULL
SUM({5}) = 5 != NULL + 5 (= NULL)
SUM({5, 3}) = 8 != NULL + 5 + 3 (= NULL)
Gibt es einen offensichtlichen Vorteil der getroffenen Wahl (SUMME ist NULL), den ich verpasst habe?
Antworten:
Ich befürchte, der Grund dafür liegt einfach darin, dass die Regeln ad-hoc festgelegt wurden (wie viele andere "Funktionen" des ISO- SQL-Standards), als SQL-Aggregationen und ihre Verbindung zur Mathematik weniger verstanden wurden als heute (*).
Dies ist nur eine der extrem vielen Inkonsistenzen in der SQL-Sprache. Sie erschweren das Unterrichten der Sprache, das Lernen, das Verstehen, die Verwendung und die Auswahl der gewünschten Sprache, aber genau so sind die Dinge. Die Regeln können aus offensichtlichen Gründen der Abwärtskompatibilität nicht "kalt" und "einfach so" geändert werden Es ist sehr wichtig, dass in einer späteren Version die Regeln so geändert werden, dass vorhandene (konforme) Implementierungen der früheren Version des Standards die neue Version "automatisch nicht erfüllen" ...)
(*) Es ist jetzt verständlicher, dass sich Aggregationen über eine leere Menge konsistenter verhalten, wenn sie systematisch den Identitätswert (= das, was Sie das "neutrale Element" nennen) des zugrunde liegenden Binäroperators zurückgeben. Der zugrunde liegende Binäroperator für COUNT und SUM ist die Addition, und sein Identitätswert ist Null. Für MIN und MAX ist dieser Identitätswert der höchste und der niedrigste Wert des jeweiligen Typs, wenn die betroffenen Typen endlich sind. Fälle wie Mittelwertbildung, harmonische Mittelwerte, Mediane usw. sind in dieser Hinsicht jedoch äußerst kompliziert und exotisch.
quelle
HIGHEST()
viele nicht ein Element des Datentypen sein, wie für Reals , wo die Identität der wäre-Infinity
(und+Infinity
fürLOWEST()
)In einem pragmatischen Sinne ist das vorhandene Ergebnis von
NULL
nützlich. Betrachten Sie die folgende Tabelle und Anweisungen:Die erste Anweisung gibt NULL und die zweite null zurück. Wenn eine leere Menge Null
SUM
zurückgibt, benötigen wir ein anderes Mittel, um eine wahre Summe von Null von einer leeren Menge zu unterscheiden, möglicherweise unter Verwendung von count. Wenn wir in der Tat Null für die leere Menge wollen, dann wird ein einfachesCOALESCE
diese Anforderung liefern.quelle
COALESCE()
so verwenden, wird die (0
) - Summe einer leeren Menge nicht von der (NULL
) - Summe unterschieden (sagen wir, die Tabelle hatte eine(10, NULL)
Zeile.SUM
eine Spalte habe und wieder null bekomme, weiß ich, ohne dass ich überprüfen muss, ob mindestens eine Nicht-NULL-Zeile verwendet wird, um mir das Ergebnis anzuzeigen.DECODE(count(c2),0,NULL,sum(c2))
es ist.Der Hauptunterschied, den ich sehe, betrifft den Datentyp. COUNT hat einen genau definierten Rückgabetyp: Eine ganze Zahl. Alle anderen hängen vom Typ der Spalte / des Ausdrucks ab, die / den sie betrachten. Ihr Rückgabetyp muss mit allen Elementen der Menge kompatibel sein (think float, currency, decimal, bcd, timespan, ...). Da es keine Menge gibt, können Sie keinen Rückgabetyp implizieren, daher ist NULL die beste Option.
Anmerkung: In den meisten Fällen können Sie einen Rückgabetyp für den betrachteten Spaltentyp implizieren, aber Sie können SUMs nicht nur für Spalten, sondern für alle Arten von Dingen ausführen. Die Implementierung eines Rückgabetyps kann unter bestimmten Umständen sehr schwierig oder gar unmöglich werden, insbesondere wenn Sie über mögliche Erweiterungen des Standards nachdenken (dynamische Typen fallen Ihnen ein).
quelle
SUM(column)
Ausdruck keinen Rückgabetyp implizieren ? Haben wir keine leeren Tabellen - und dort haben alle Spalten definierte Typen? Warum sollte es bei einer leeren Ergebnismenge anders sein?24 + 56.07 + '2012-10-05' + 'Red'
sein? Ich meine, es gibt keinen Grund zur Sorge, wie sichSUM()
das verhält, wenn wir ein Problem bei der Definition der Addition haben.