GROUPING SETS für flexible Report-Kombinationen
AI generated
SELECT
JOIN
SQL · GROUPING SETS · Reporting · Subtotale
GROUPING SETS
gezielte Kombinationen statt vollem CUBE

GROUPING SETS berechnen genau die Subtotal-Kombinationen, die ein Report tatsächlich braucht, in einer einzigen Abfrage mit einem einzigen Table-Scan. Dieser Artikel zeigt, wie sich GROUPING SETS von ROLLUP und CUBE unterscheiden, warum sie bei individuell zugeschnittenen Reports weniger überflüssige Zeilen erzeugen, und wie die GROUPING-Funktion echte NULL-Werte von Subtotal-Zeilen zuverlässig trennt.

14 Min. Lesezeit GROUPING SETS · GROUPING() · ROLLUP · CUBE ANSI SQL · PostgreSQL · SQL Server · Oracle

1. Was GROUPING SETS lösen und wofür sie stehen

GROUPING SETS lösen ein Problem, das bei individuell zugeschnittenen Reports häufig auftritt: Ein Report soll nicht jede denkbare Kombination von Gruppierungsspalten enthalten, sondern nur eine bewusst ausgewählte Teilmenge davon. Ein Vertriebsreport könnte etwa Subtotale nach Region, nach Produktkategorie und einen Gesamt-Grand-Total benötigen, aber ausdrücklich keine Kombination aus Region und Produktkategorie gleichzeitig, weil diese Detailtiefe für den Adressaten des Reports nicht relevant ist.

Ohne GROUPING SETS müsste ein solcher Report entweder über mehrere separate Abfragen mit anschließendem UNION ALL zusammengestellt werden, oder über CUBE, das automatisch alle möglichen Kombinationen erzeugt und die nicht benötigten Zeilen im Nachhinein wieder herausfiltert. Beide Alternativen sind entweder umständlich oder verschwenden Rechenleistung für Kombinationen, die niemand sehen möchte. GROUPING SETS lösen dieses Problem, indem die gewünschten Kombinationen explizit als Liste angegeben werden, und die Datenbank berechnet in einem einzigen Table-Scan genau diese Kombinationen, nicht mehr und nicht weniger.

Dieser Artikel erklärt die Grundsyntax von GROUPING SETS, grenzt sie klar von ROLLUP und CUBE ab, zeigt die GROUPING-Funktion zur Unterscheidung von echtem NULL und Subtotal-Zeilen, und arbeitet typische Anwendungsfälle für individuell zugeschnittene Kreuztabellen-Reports durch.

2. Grundsyntax: Kombinationen explizit auflisten

Die Grundsyntax von GROUPING SETS listet jede gewünschte Kombination von Gruppierungsspalten explizit in Klammern auf, getrennt durch Kommata, innerhalb einer gemeinsamen GROUP BY GROUPING SETS-Klausel. Jede einzelne Klammergruppe entspricht dabei einer eigenständigen Gruppierungsebene, die in der Ergebnismenge als eigene Zeilen erscheint, genau als hätte man für jede Kombination eine separate GROUP-BY-Abfrage geschrieben und die Ergebnisse mit UNION ALL zusammengeführt.

Eine leere Klammergruppe, dargestellt als (), steht dabei für die Gruppierung über die gesamte Tabelle ohne jede Aufteilung, also den klassischen Grand Total. GROUPING SETS erlauben es, diesen Grand Total zusammen mit beliebigen anderen Subtotal-Ebenen in derselben Abfrage zu kombinieren, ohne dass eine zusätzliche separate Abfrage für den Gesamtwert nötig wäre.


-- GROUPING SETS: exactly the subtotal combinations we need, nothing more
SELECT
    region,
    product_category,
    SUM(total_amount) AS revenue
FROM orders
GROUP BY GROUPING SETS (
    (region),              -- subtotal per region
    (product_category),    -- subtotal per category
    ()                     -- grand total across everything
)
ORDER BY region, product_category;

3. GROUPING SETS vs. mehrere Abfragen mit UNION ALL

Vor der Einführung von GROUPING SETS im SQL-Standard wurde genau dieses Muster über mehrere separate GROUP-BY-Abfragen realisiert, die anschließend mit UNION ALL zu einem gemeinsamen Ergebnis zusammengeführt wurden. Funktional liefert dieser Ansatz dasselbe Ergebnis wie GROUPING SETS, hat aber einen entscheidenden Nachteil: Jede der separaten Abfragen scannt die zugrunde liegende Tabelle unabhängig, wodurch bei drei gewünschten Kombinationen dreimal über dieselben Daten gelesen wird, statt nur einmal.

GROUPING SETS lösen dieses Problem, indem der Query-Planer moderner Datenbanksysteme die Tabelle nur einmal liest und die verschiedenen Gruppierungsebenen aus diesem einzigen Datendurchlauf ableitet, ähnlich wie es bereits bei ROLLUP und CUBE der Fall ist. Der Performance-Unterschied zwischen UNION ALL über separate Abfragen und GROUPING SETS wächst proportional mit der Anzahl der gewünschten Kombinationen und der Größe der zugrunde liegenden Tabelle, was GROUPING SETS bei umfangreichen Reports mit vielen Subtotal-Ebenen zur klar überlegenen Wahl macht.


-- The old way: three table scans combined with UNION ALL
SELECT region, NULL AS product_category, SUM(total_amount) AS revenue
FROM orders GROUP BY region
UNION ALL
SELECT NULL, product_category, SUM(total_amount)
FROM orders GROUP BY product_category
UNION ALL
SELECT NULL, NULL, SUM(total_amount)
FROM orders;
-- Same result as the GROUPING SETS query above, but three full scans

4. Die GROUPING-Funktion: echtes NULL von Subtotal unterscheiden

Ein zentrales Problem bei GROUPING SETS, das genauso bei ROLLUP und CUBE auftritt, betrifft die Unterscheidung zwischen einem echten NULL-Wert in der Gruppierungsspalte und einem NULL, das die Datenbank künstlich einfügt, um eine Subtotal-Zeile darzustellen, in der diese Spalte nicht Teil der Gruppierung war. Enthält die Spalte region tatsächlich einen NULL-Wert, weil eine Bestellung keiner Region zugeordnet wurde, sieht diese Zeile in der Ausgabe identisch aus wie eine Subtotal-Zeile, die region absichtlich zusammenfasst.

Die GROUPING-Funktion löst diese Mehrdeutigkeit auf: GROUPING(spalte) liefert 1, wenn die Zeile eine Subtotal-Zeile ist, in der diese Spalte nicht Teil der aktuellen Gruppierungsebene war, und 0, wenn die Spalte tatsächlich Teil der Gruppierung war, unabhängig davon, ob ihr Wert selbst NULL ist oder nicht. Damit lässt sich in der SELECT-Liste oder in einer nachgelagerten Anwendung zuverlässig zwischen "diese Region ist unbekannt" und "dies ist die Subtotal-Zeile über alle Regionen hinweg" unterscheiden, was für die korrekte Darstellung in einem Reporting-Tool unverzichtbar ist.


-- GROUPING() disambiguates real NULL from subtotal rows
SELECT
    region,
    product_category,
    GROUPING(region)           AS is_region_subtotal,
    GROUPING(product_category) AS is_category_subtotal,
    SUM(total_amount)          AS revenue
FROM orders
GROUP BY GROUPING SETS (
    (region),
    (product_category),
    ()
)
ORDER BY region, product_category;

-- is_region_subtotal = 1 marks rows where region was collapsed,
-- not rows where region happens to be genuinely unknown

5. Abgrenzung zu ROLLUP und CUBE

GROUPING SETS sind konzeptionell die allgemeinste der drei verwandten Konstruktionen, weil sowohl ROLLUP als auch CUBE sich als Kurzschreibweisen für bestimmte, feste Muster von GROUPING SETS auffassen lassen. ROLLUP(a, b, c) erzeugt eine hierarchische Abfolge von Kombinationen, (a, b, c), (a, b), (a), (), also genau n plus eins Kombinationen bei n Spalten, passend für hierarchische Daten wie Jahr, Quartal, Monat. CUBE(a, b, c) dagegen erzeugt alle zwei hoch n möglichen Kombinationen dieser Spalten, unabhängig von einer Hierarchie zwischen ihnen.

GROUPING SETS erlauben dagegen eine völlig freie Auswahl, die weder der strikten Hierarchie von ROLLUP noch der vollständigen Kombinatorik von CUBE folgen muss. Man kann mit GROUPING SETS beispielsweise gezielt (region, produktkategorie), (region) und () kombinieren, ohne dass automatisch auch (produktkategorie) allein erzeugt wird, was mit CUBE technisch nicht möglich wäre, ohne die überflüssige Kombination anschließend wieder herauszufiltern. Diese Freiheit macht GROUPING SETS zur richtigen Wahl, sobald ein Report eine Kombination benötigt, die weder rein hierarchisch noch vollständig kombinatorisch ist.

6. Die leere Gruppierung für den Gesamt-Grand-Total

Die leere Klammergruppe () innerhalb von GROUPING SETS verdient besondere Aufmerksamkeit, weil sie oft übersehen wird, obwohl sie in nahezu jedem Report mit Subtotalen auch einen Gesamtwert über die komplette Tabelle liefern soll. Ohne die leere Gruppierung enthält das Ergebnis nur die einzelnen Subtotal-Ebenen, aber keinen übergeordneten Gesamtwert, was in einem tabellarischen Report meist als fehlende letzte Zeile auffällt.

Ein häufiger Fehler bei GROUPING SETS besteht darin, die leere Gruppierung versehentlich wegzulassen, weil sie syntaktisch leicht zu übersehen ist zwischen den anderen, inhaltlich offensichtlicheren Kombinationen. Wer regelmäßig Reports mit GROUPING SETS erstellt, sollte sich angewöhnen, die leere Gruppierung standardmäßig mit aufzunehmen, es sei denn, ein Grand Total ist für den konkreten Report ausdrücklich nicht gewünscht, etwa weil er fachlich keinen Sinn ergibt, wenn die einzelnen Subtotale unterschiedliche Einheiten oder Kontexte repräsentieren.


-- Marking the grand total row explicitly with GROUPING()
SELECT
    COALESCE(region, 'ALL REGIONS') AS region_label,
    SUM(total_amount) AS revenue,
    GROUPING(region) AS is_grand_total
FROM orders
GROUP BY GROUPING SETS (
    (region),
    ()
)
ORDER BY is_grand_total, region_label;

7. Performance: ein Scan für alle Kombinationen

Der Performance-Vorteil von GROUPING SETS gegenüber separaten Abfragen mit UNION ALL ergibt sich aus derselben Logik wie bei Conditional Aggregation: Die Datenbank muss die zugrunde liegende Tabelle nur einmal lesen, unabhängig davon, wie viele Gruppierungskombinationen in der GROUPING-SETS-Liste stehen. Moderne Query-Planer erkennen GROUPING SETS als eine einzige logische Operation und wählen typischerweise einen Hash- oder Sort-basierten Aggregationsplan, der die Eingabedaten einmal durchläuft und für jede Zeile parallel alle relevanten Gruppierungsebenen aktualisiert.

Bei sehr vielen unterschiedlichen Kombinationen kann der Speicherbedarf für die parallel geführten Zwischenaggregate allerdings ansteigen, weil der Planer für jede Kombination eine eigene Hash-Tabelle oder Sortierstruktur im Speicher halten muss. In der Praxis bleibt dieser Mehraufwand aber deutlich geringer als der Aufwand mehrerer vollständiger Table-Scans, weshalb GROUPING SETS bei Reports mit mehr als zwei oder drei gewünschten Subtotal-Kombinationen praktisch immer die performantere Wahl gegenüber separaten Abfragen sind.

8. Typische Reports: Kreuztabellen mit gezielten Subtotalen

Der klassische Anwendungsfall für GROUPING SETS ist ein Kreuztabellen-Report, der Umsatz gleichzeitig nach Region, nach Vertriebskanal und als Gesamtwert ausweisen soll, aber ausdrücklich keine feingranulare Kombination aus Region und Vertriebskanal benötigt, weil diese Detailtiefe für die Zielgruppe des Reports zu unübersichtlich wäre. GROUPING SETS bilden genau diese drei gewünschten Ebenen in einer einzigen Abfrage ab, ohne die vierte, nicht benötigte Kombination zu erzeugen.

Ein weiterer typischer Anwendungsfall betrifft Reports mit gemischter Granularität, etwa ein Finanzreport, der Kostenstellen auf oberster Ebene, aber Produktlinien auf einer feineren Detailebene ausweisen soll, während eine Kombination aus Kostenstelle und Produktlinie fachlich nicht sinnvoll wäre, weil beide Dimensionen unabhängig voneinander organisiert sind. GROUPING SETS erlauben genau diese asymmetrische Mischung unterschiedlicher Detailtiefen in einem einzigen, konsistenten Reporting-Query, was mit ROLLUP oder CUBE allein nicht direkt abbildbar wäre.


-- Mixed granularity report: cost centers at top level, product lines at detail level
SELECT
    cost_center,
    product_line,
    SUM(amount) AS total_amount,
    GROUPING(cost_center) AS is_cost_center_subtotal,
    GROUPING(product_line) AS is_product_line_subtotal
FROM financial_entries
GROUP BY GROUPING SETS (
    (cost_center),
    (product_line),
    ()
)
ORDER BY cost_center, product_line;

9. GROUPING SETS, ROLLUP und CUBE im Vergleich

Die folgende Übersicht vergleicht die drei verwandten Konstruktionen für mehrstufige Aggregation und ordnet ein, wann GROUPING SETS die richtige Wahl sind.

Konstruktion Erzeugte Kombinationen Kontrolle Geeignet für
ROLLUP(a, b, c) n plus 1, hierarchisch Feste Hierarchie-Reihenfolge Jahr, Quartal, Monat
CUBE(a, b, c) 2 hoch n, alle Kombinationen Keine, alles wird erzeugt Vollständige Kreuztabellen
GROUPING SETS (...) Beliebig, frei wählbar Volle Kontrolle über jede Kombination Individuell zugeschnittene Reports

In der Praxis sind GROUPING SETS die richtige Wahl, sobald ein Report weder die strikte Hierarchie von ROLLUP noch die vollständige Kombinatorik von CUBE benötigt, sondern eine bewusst kuratierte Teilmenge an Subtotalen, die exakt den Anforderungen der Report-Adressaten entspricht, ohne überflüssige Zeilen zu erzeugen, die anschließend wieder herausgefiltert werden müssten.

Mironsoft

Individuelle Reporting-Queries und Aggregations-Design

Zu viele oder zu wenige Subtotal-Zeilen im Report?

Wir entwerfen Reporting-Abfragen mit GROUPING SETS, die exakt die Subtotal-Kombinationen liefern, die euer Report tatsächlich braucht, ohne überflüssige oder fehlende Zeilen.

Report-Design

Passgenaue Subtotal-Kombinationen statt starrem ROLLUP oder vollem CUBE

Query-Refactoring

Mehrere UNION-ALL-Abfragen zu einer performanten GROUPING-SETS-Abfrage zusammenführen

Dashboard-Integration

Korrekte Darstellung von Subtotal- und Grand-Total-Zeilen mit der GROUPING-Funktion

Wer GROUPING SETS gezielt für individuell zugeschnittene Subtotal-Kombinationen einsetzt, vermeidet sowohl die Umständlichkeit mehrerer UNION-ALL-Abfragen als auch die Verschwendung eines vollständigen CUBE, wenn nur ein Bruchteil der möglichen Kombinationen fachlich überhaupt gebraucht wird.

10. Zusammenfassung

GROUPING SETS berechnen genau die gewünschten Kombinationen von Gruppierungsspalten in einer einzigen Abfrage mit einem einzigen Table-Scan, statt entweder mehrere separate Abfragen mit UNION ALL zusammenzuführen oder mit CUBE alle Kombinationen zu erzwingen und die überflüssigen anschließend herauszufiltern. Jede Klammergruppe in der GROUPING-SETS-Liste steht für eine eigenständige Gruppierungsebene, die leere Klammergruppe () für den Grand Total über die gesamte Tabelle.

Die GROUPING-Funktion trennt zuverlässig echte NULL-Werte in einer Gruppierungsspalte von künstlichen NULL-Werten, die eine Subtotal-Zeile markieren. Im Vergleich zu ROLLUP, das eine feste Hierarchie erzeugt, und CUBE, das alle möglichen Kombinationen liefert, bieten GROUPING SETS die größte Flexibilität für individuell zugeschnittene Reports mit gemischter oder asymmetrischer Detailtiefe.

GROUPING SETS: das Wichtigste auf einen Blick

Freie Kombination

Jede Klammergruppe eine eigene Gruppierungsebene, beliebig frei wählbar, nicht hierarchisch oder vollständig.

Grand Total

Die leere Klammergruppe () liefert den Gesamtwert über die komplette Tabelle.

GROUPING-Funktion

GROUPING(spalte) = 1 markiert Subtotal-Zeilen, unterscheidet sie von echtem NULL.

Performance

Ein Table-Scan für alle Kombinationen, statt mehrerer Scans bei separaten UNION-ALL-Abfragen.

11. FAQ: GROUPING SETS

1Was sind GROUPING SETS?
Explizite Liste beliebiger Gruppierungskombinationen in einer einzigen Abfrage.
2Was bedeutet die leere Gruppierung?
Sie liefert den Grand Total über die gesamte Tabelle ohne Aufteilung.
3Unterschied zu ROLLUP?
ROLLUP erzeugt feste Hierarchie, GROUPING SETS erlauben freie Auswahl.
4Unterschied zu CUBE?
CUBE erzeugt alle Kombinationen, GROUPING SETS nur die explizit genannten.
5Wozu die GROUPING-Funktion?
Markiert Subtotal-Zeilen, unterscheidet sie von echten NULL-Werten.
6Warum schneller als UNION ALL?
Nur ein Table-Scan statt eines Scans pro separater Abfrage.
7Echtes NULL erkennbar?
Ja, mit der GROUPING-Funktion, sonst sehen beide Fälle identisch aus.
8Wann GROUPING SETS wählen?
Wenn weder strikte Hierarchie noch volle Kombinatorik gebraucht wird.
9Unterschiedliche Spaltenanzahl möglich?
Ja, jede Klammergruppe kann eine andere Anzahl Spalten enthalten.
10Leere Gruppierung leicht vergessen?
Ja, ein häufiger Fehler, obwohl viele Reports einen Gesamtwert brauchen.