GROUP BY ist eine SQL-Klausel, die Zeilen mit gleichen Werten in den genannten Spalten zu Gruppen zusammenfasst. Erst durch diese Gruppierung werden Aggregatfunktionen wie COUNT, SUM, AVG, MIN oder MAX sinnvoll: Sie berechnen dann einen Wert pro Gruppe statt über alle Zeilen.
Das Grundprinzip
Die folgende Abfrage zählt für jede Kategorie, wie viele Artikel es gibt und wie hoch der Umsatz ist:
SELECT kategorie, COUNT(*) AS anzahl, SUM(preis) AS umsatz
FROM artikel
GROUP BY kategorie;
Jede Spalte im SELECT, die nicht in einer Aggregatfunktion steht, muss in der GROUP BY-Liste auftauchen. Sonst weiß die Datenbank nicht, welchen Einzelwert sie für die Gruppe zeigen soll — PostgreSQL und MySQL im strengen Modus brechen dann mit einem Fehler ab.
Gruppieren nach mehreren Spalten
Werden mehrere Spalten angegeben, bildet jede Kombination ihrer Werte eine eigene Gruppe:
SELECT jahr, kategorie, SUM(umsatz) AS summe
FROM verkauf
GROUP BY jahr, kategorie;
So erhält man zum Beispiel Umsätze je Jahr und Kategorie. Zeilen mit NULL in der Gruppenspalte landen gemeinsam in einer Gruppe — NULL gilt dabei als ein eigener Wert.
Die Reihenfolge der Klauseln
Die logische Ausführungsreihenfolge in SQL ist entscheidend: Zuerst filtert WHERE einzelne Zeilen heraus, dann fasst GROUP BY die verbliebenen Zeilen zu Gruppen zusammen. Möchte man die fertigen Gruppen filtern, braucht es die HAVING-Klausel — eine Bedingung auf das Aggregat gehört also nie in WHERE, sondern in HAVING.
Teilsummen mit GROUPING SETS, ROLLUP und CUBE
PostgreSQL, SQL Server, Oracle und neuere MySQL-Versionen können mit GROUPING SETS gezielt mehrere Gruppierungsebenen in einer Abfrage erzeugen. ROLLUP ergänzt Zwischensummen von der feinsten bis zur gröbsten Ebene, CUBE alle Kombinationen — praktisch für Berichte.
Einordnung
GROUP BY ist neben JOIN, Subquery und Window Functions eine der zentralen Auswertungstechniken von SQL. Wer mehrstufige Auswertungen strukturieren will, kann die Gruppierung auch in einen CTE (WITH-Klausel) auslagern. Die Sprache selbst erklärt SQL-Grundlagen. Wer doppelte Zeilen aus dem Ergebnis entfernen will, nutzt DISTINCT.