ProgrammierungBackend-Entwickler, BI-Analytiker

Wie implementiert man zuverlässige bedingte Aggregationen in SQL beim Erstellen von Berichten mit mehreren Filtern? Welche Feinheiten gibt es beim Mischen von HAVING, CASE und Aggregatfunktionen?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort.

Bedingte Aggregation ist eine klassische Aufgabe für die Berichterstattung. Ursprünglich wurden separate Abfragen mit Filtern zum Zählen verschiedener Kennzahlen erstellt. Bald gab es eine kompaktere Lösung — die bedingte Aggregation mit CASE innerhalb von Aggregatfunktionen (z.B. SUM(CASE WHEN ...)). Das Problem zeigt sich, wenn Filter, Gruppierungen und Zwischensummen kombiniert werden: Man kann leicht falsche Summen erhalten oder das Ergebnis falsch interpretieren.

Lösung: Verwenden Sie bedingte Aggregation innerhalb von Aggregatfunktionen. Zum Beispiel muss man die Anzahl der "in Bearbeitung" und "abgeschlossenen" Aufträge für alle Mitarbeiter ausgeben:

SELECT employee_id, SUM(CASE WHEN status = 'processing' THEN 1 ELSE 0 END) as processing_count, SUM(CASE WHEN status = 'done' THEN 1 ELSE 0 END) as done_count FROM Orders GROUP BY employee_id;

Wichtige Merkmale:

  • Unabhängig vom WHERE-Filter werden alle benötigten Summen in einer Abfrage berechnet.
  • CASE innerhalb von SUM ermöglicht den Aufbau komplexer Mehrfachberichte.
  • HAVING wird auf bereits aggregierte Daten angewendet, um die Ergebnisse der Gruppierung nachzufiltern.

Fangfragen.

Was passiert, wenn die CASE-Anweisung NULL anstelle von 0 zurückgibt?

Die Aggregatfunktion SUM ignoriert NULL. Daher werden die fehlenden Zeilen nicht berücksichtigt, wenn man CASE WHEN ... THEN 1 END schreibt. Es ist besser, immer ELSE 0 explizit anzugeben.

SUM(CASE WHEN status = 'processing' THEN 1 ELSE 0 END)

Kann ein WHERE-Filter die Gesamtsumme der Status bei bedingter Aggregation ändern?

Ja: Wenn das Haupt-WHERE die Auswahl einschränkt (z.B. WHERE region = 'west'), werden die Berechnungen nur auf die gefilterten Daten durchgeführt. Für globale Summen verwenden Sie eine Unterabfrage oder entfernen Sie den Filter.

Kann man HAVING verwenden, um Zeilen vor der Gruppierung zu filtern?

Nein. HAVING filtert bereits gruppierte Daten nach Aggregaten. Die Filterung der Ausgangszeilen erfolgt über WHERE.

Typische Fehler und Anti-Pattern

  • ELSE fehlt, CASE gibt NULL zurück, Ergebnisse sind falsch.
  • WHERE und HAVING werden vermischt, wodurch falsche Zeilen erhalten werden.
  • Es werden mehrere Abfragen anstelle einer einzigen mit CASE verwendet.

Beispiel aus dem Leben

Negativer Fall

In einem Analysebericht wurde verwendet:

SUM(CASE WHEN status = 'approved' THEN 1 END)

Es gab viele NULL, die Endsummen waren zu niedrig. Aufgrund des WHERE-Filters gingen einige benötigte Zeilen verloren.

Vorteile:

  • Der Code ist kurz.

Nachteile:

  • Unkorrekte Ergebnisse, der Bericht wurde dem Unternehmen falsch erklärt.

Positiver Fall

Verwendet wurde:

SUM(CASE WHEN status = 'approved' THEN 1 ELSE 0 END)

Der Code wurde in einer einzigen Abfrage gehalten, Filter auf die Gesamtergebnisse wurden über HAVING durchgeführt.

Vorteile:

  • Korrekte, transparente Kennzahlen.
  • Einfach, einen neuen Status hinzuzufügen.

Nachteile:

  • Anfragen werden länger, es ist Genauigkeit mit den Filtern erforderlich.