Lässt es sich mit cremefarbenem Papier, einer Tönung, mehr Kontrast oder größerer Schrift besser lesen? Wählen Sie Ihre Farben und Ihre Schrift, einmalig für alle Seiten.

Kostenlose Lektion

Zwischensummen mit ROLLUP und CUBE

Nach dieser Lektion: Ich kann in einer Abfrage Summen auf mehreren Ebenen berechnen.

Lektion, 55 Min.Keine Befehle

Wie berechnet man Zwischensummen in SQL?

ROLLUP und CUBE sind Erweiterungen von GROUP BY. Sie liefern Summen auf mehreren Ebenen in einer Abfrage: je Filiale und Produkt, je Filiale und insgesamt.

So ersetzen Sie drei Abfragen durch eine. Der Bericht hat dann Zwischensummen und eine Gesamtsumme.

Am Ende dieser Lektion

Notiz

Ich kann in einer Abfrage Summen auf mehreren Ebenen berechnen.

Schlüsselwörter

BegriffWas er bedeutetBeispiel
Zwischensummedie Summe einer Gruppe innerhalb einer größeren Gruppe
ROLLUPbildet Summen für jede Ebene von der feinsten bis zur Gesamtsumme
CUBEbildet Summen für jede Kombination der Spalten
FILTERlässt eine Aggregatfunktion nur ausgewählte Zeilen zählensum(x) filter (where y = 1)
Kreuztabellemacht aus den Werten einer Spalte eigene Spalten

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

Rollup fügt Zwischensummen und die Gesamtsumme hinzu

Ein gewöhnliches group by filiale, produkt gibt eine Zeile je Paar. Eine Zwischensumme je Filiale fehlt.

group by rollup(filiale, produkt) rollt die Spalten von rechts nach links auf: erst je Filiale und Produkt, dann je Filiale allein, dann alles zusammen.

In den Zusatzzeilen steht NULL für die Spalte, die zusammengefasst wurde.

Ein Ausschnitt des Ergebnisses

filialeproduktumsatz_euroEbene
BerlinKaffee66Filiale und Produkt
BerlinNULL95Zwischensumme Berlin
HamburgNULL93Zwischensumme Hamburg
NULLNULL340Gesamtsumme

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

Probieren Sie es: Rollup über zwei Spalten

Code: duckdb
-- Je Filiale und Produkt, je Filiale, und insgesamt.
select filiale, produkt, sum(betrag_euro) as umsatz_euro
from verkaeufe
group by rollup(filiale, produkt)
order by filiale nulls last, produkt nulls last;
-- Vertauschen Sie die Reihenfolge: rollup(produkt, filiale).

NULL in einer Summenzeile heißt alle

Ein NULL in einer Zusatzzeile sagt nicht, dass ein Wert fehlt. Es sagt, dass diese Spalte über alle Werte zusammengefasst wurde.

Für den Bericht schreiben Sie ein Wort hin: coalesce(produkt, 'alle Produkte') ersetzt NULL durch den Text.

Hat Ihre Tabelle echte NULL-Werte, nutzen Sie grouping(produkt): Es ist 1 in einer Summenzeile und sonst 0.

Probieren Sie es: die Summenzeilen beschriften

Code: duckdb
-- NULL steht hier für "alle"; coalesce schreibt das Wort hin.
select filiale, coalesce(produkt, 'alle Produkte') as produkt,
       sum(betrag_euro) as umsatz_euro
from verkaeufe
group by rollup(filiale, produkt)
order by filiale nulls last, produkt;

Ein häufiger Fehler

Warnung

Viele lesen das NULL einer Summenzeile als fehlenden Wert. Es ist ein Zeichen für alle Werte. Gibt es in Ihren Daten auch echte NULL, trennt nur grouping() die beiden Fälle sicher.

Cube bildet jede Kombination

rollup kennt eine Reihenfolge: erst die Filiale, dann das Produkt. Eine Summe je Produkt über alle Filialen gibt es dort nicht.

cube(filiale, produkt) bildet alle Kombinationen: beide Spalten, nur Filiale, nur Produkt und keine.

Das sind vier Ebenen statt drei. Bei vielen Spalten wächst die Zahl schnell.

Probieren Sie es: Cube über zwei Spalten

Code: duckdb
-- Cube bildet auch die Summe je Produkt über alle Filialen.
select filiale, produkt, sum(betrag_euro) as umsatz_euro
from verkaeufe
group by cube(filiale, produkt)
order by filiale nulls last, produkt nulls last;

Filter und eine Kreuztabelle von Hand

filter (where ...) hinter einer Aggregatfunktion lässt sie nur Zeilen zählen, die die Bedingung erfüllen.

Mit einem filter je Produkt entsteht eine Kreuztabelle: Die Produkte stehen nebeneinander als Spalten, die Filialen untereinander.

So ist ein Pivot von Hand geschrieben, ganz ohne Spezialsyntax.

Probieren Sie es: ein Pivot mit filter

Code: duckdb
-- Eine Spalte je Produkt, gezählt mit filter.
select filiale,
       sum(betrag_euro) as gesamt,
       sum(betrag_euro) filter (where produkt = 'Kaffee') as kaffee,
       sum(betrag_euro) filter (where produkt = 'Tee') as tee,
       sum(betrag_euro) filter (where produkt = 'Kakao') as kakao
from verkaeufe
group by filiale
order by filiale;
-- Fügen Sie eine Spalte nur für den 3. März hinzu.

Sie unterrichten eine Gruppe? Weisen Sie dieses Modul Ihren Studierenden zu, mit Handbuch für Lehrende, automatisch geprüften Aufgaben und einem Lab für jede Person.