Bedingte Aggregation wird verwendet, wenn man Werte aggregieren möchte (zum Beispiel Summen oder Mengen) basierend auf unterschiedlichen Bedingungen innerhalb einer einzigen Abfrage. Historisch mussten SQL-Entwickler, um solche Ziele zu erreichen, mehrere Unterabfragen schreiben oder Joins und Gruppierungen separat für jede Kategorie vornehmen, was zu weniger lesbarem und weniger performantem Code führte.
Das Problem lag in der Schwierigkeit, mehrere Aggregationen gleichzeitig mit unterschiedlichen Bedingungen zu berechnen – jede einzelne Aggregation erfordert normalerweise eine Filterung, und die einfache Anwendung von SUM() oder COUNT() berücksichtigt die erforderliche Bedingung nicht innerhalb der Aggregatfunktion.
Lösung – die Verwendung der CASE-Konstruktion innerhalb der Aggregatfunktion, die es ermöglicht, Aggregationen nach verschiedenen Bedingungen zur Laufzeit zu "trennen", ohne auf mehrere Joins zurückgreifen zu müssen:
Beispielcode:
SELECT department, SUM(CASE WHEN status = 'approved' THEN amount ELSE 0 END) AS approved_sum, SUM(CASE WHEN status = 'pending' THEN amount ELSE 0 END) AS pending_sum, COUNT(CASE WHEN status = 'rejected' THEN 1 END) AS rejected_count FROM payments GROUP BY department;
Wichtige Merkmale:
Kann man auf die CASE-Konstruktion für bedingte Aggregation verzichten?
Eine falsche Antwort wäre, WHERE direkt in der Abfrage zusammen mit der Aggregatfunktion zu verwenden. Tatsächlich filtert WHERE die Zeilen vor der Aggregation, nicht innerhalb jeder Aggregatspalte.
Beispielcode (falsche Methode):
SELECT COUNT(*) FROM payments WHERE status = 'approved'; SELECT COUNT(*) FROM payments WHERE status = 'pending';
Diese Abfragen können nicht in eine Ergebniszeile nach verschiedenen Bedingungen ohne CASE zusammengefasst werden.
Was passiert, wenn NULL innerhalb des bedingten Ausdrucks verwendet wird?
Wenn CASE keinen alternativen Wert zurückgibt, wird standardmäßig NULL verwendet, und die Aggregatfunktion ignoriert NULL.
Beispielcode:
SUM(CASE WHEN status = 'approved' THEN amount END) -- Wenn der Status nicht 'approved' ist, gibt es NULL, und die Zeile wird in SUM ignoriert
Kann man IF anstelle von CASE verwenden?
In einigen SQL-Dialekten (zum Beispiel MySQL) ist das möglich, aber dieser Code wird zwischen verschiedenen Datenbanken nicht portierbar. Verwenden Sie in universellen Abfragen immer CASE.
Ein Analyst versuchte, Summen nach jedem Status zu berechnen, indem er mehrere separate Unterabfragen schrieb. Der externe Bericht wurde kompliziert, und das Hinzufügen neuer Status erforderte jedes Mal eine Neuschreibung des Codes.
Vorteile:
Ein Entwickler verwendete CASE in einer allgemeinen Abfrage und erstellte einen universellen Bericht, der die Möglichkeit bot, neue Status einfach über eine einfache Bearbeitung einer Abfrage zu erweitern.
Vorteile: