Kodokon kodokon.com

HAVING und fortgeschrittene Aggregationen

Filtere nach der Aggregation mit HAVING und pivotiere deine Daten mit CASE WHEN innerhalb von Aggregatfunktionen.

8 Min. · 3 Fragen

Diese Lektion in Kodokon öffnen

Du kennst GROUP BY bereits. Dieses Modul geht das an, was eine korrekte Abfrage von einer professionellen unterscheidet: das Filtern nach der Aggregation, bedingte Aggregate und ein solides Verständnis der Auswertungsreihenfolge. Zum Üben öffnest du sqliteonline.com (SQLite-Engine) oder startest sqlite3 in einem Terminal: Jede Lektion liefert dir die nötigen CREATE TABLE- und INSERT-Anweisungen. Kopiere diesen Datensatz, bevor du die Beispiele ausführst.

SQL
CREATE TABLE orders (
  id INTEGER PRIMARY KEY,
  customer TEXT NOT NULL,
  category TEXT NOT NULL,
  amount REAL NOT NULL,
  status TEXT NOT NULL
);

INSERT INTO orders (customer, category, amount, status)
VALUES
  ('alice', 'books', 42.0, 'paid'),
  ('alice', 'games', 55.0, 'paid'),
  ('alice', 'books', 18.5, 'refunded'),
  ('bruno', 'games', 70.0, 'paid'),
  ('bruno', 'books', 12.0, 'paid'),
  ('chloe', 'games', 95.0, 'paid'),
  ('chloe', 'books', 30.0, 'paid'),
  ('david', 'books', 8.0, 'refunded');
Datensatz für diese Lektion, führe ihn zuerst aus.

Die logische Auswertungsreihenfolge ist der Schlüssel: FROMWHEREGROUP BYHAVINGSELECTORDER BY. WHERE filtert Zeilen vor der Gruppierung; HAVING filtert Gruppen, nachdem die Aggregate berechnet wurden. Genau deshalb ist WHERE SUM(amount) > 90 unzulässig: In der WHERE-Phase existiert noch keine Summe. Hier behalten wir nur Kundinnen und Kunden, deren bezahlte Summe 90 übersteigt (erwartet: alice und chloe).

SQL
SELECT customer,
       COUNT(*) AS nb_orders,
       SUM(amount) AS total
FROM orders
WHERE status = 'paid'
GROUP BY customer
HAVING SUM(amount) > 90;
WHERE entfernt Zeilen, HAVING entfernt Gruppen.

Das zweite unverzichtbare Muster ist das bedingte Aggregat. Indem du ein CASE WHEN in SUM oder COUNT einschiebst, berechnest du mehrere Kennzahlen in einem einzigen Durchlauf über die Tabelle, wo ein Anfänger drei getrennte Abfragen ausführen würde. Das ist die Standardtechnik, um Zeilen in Spalten zu pivotieren.

SQL
SELECT customer,
  SUM(CASE WHEN category = 'books'
      THEN amount ELSE 0 END) AS books_total,
  SUM(CASE WHEN category = 'games'
      THEN amount ELSE 0 END) AS games_total
FROM orders
WHERE status = 'paid'
GROUP BY customer;
Zeilen → Spalten in einem einzigen Lesevorgang pivotieren.

Wissenscheck

Stelle sicher, dass du die wichtigsten Punkte dieser Lektion behalten hast.

  1. In welcher logischen Reihenfolge wertet die Engine diese Klauseln aus?
    • WHERE → GROUP BY → HAVING
    • HAVING → WHERE → GROUP BY
    • GROUP BY → HAVING → WHERE
  2. Welche Bedingung sollte eher in WHERE als in HAVING bleiben?
    • SUM(amount) > 100
    • status = 'paid'
    • COUNT(*) >= 2
  3. Was berechnet SUM(CASE WHEN category = 'books' THEN amount ELSE 0 END)?
    • Die Summe aller Bestellungen
    • Die Summe nur der Zeilen in der Kategorie 'books'
    • Die Anzahl der Zeilen in der Kategorie 'books'
    • Die Summe der Zeilen außerhalb von 'books'