Direkt zum Hauptinhalt springen
eLearner.app
Modul 7 · Lektion 2 von 426/57 im Kurs~14 min
Lektionen des Moduls (2/4)

Window-Funktionen: Rankings und Berechnungen pro Gruppe

Eine Fensterfunktion ist eine Funktion, die eine „Gruppe von Zeilen“ bearbeitet. (das Fenster), aber – im Gegensatz zu GROUP BYreduziert nicht die Anzahl von Zeilen: Ein über das Fenster berechneter Wert wird an jede Zeile des angehängt Endergebnis.

Es ist das richtige Werkzeug für Rankings, fortlaufende Nummerierung und Prozentsätze über eine Gruppensumme und viele andere Vorgänge, die umständlich sind oder unmöglich mit GROUP BY.

Die Syntax: function() OVER (…)

SQL
ROW_NUMBER() OVER (PARTITION BY colonna ORDER BY colonna2)

Komponenten:

  • PARTITION BY – definiert die „Gruppen“ (wie GROUP BY, aber die Zeilen getrennt bleiben);
  • ORDER BY innerhalb von OVER(…) – definiert die Reihenfolge innerhalb der Partition.

OVER () (leere Klammern) bedeutet „die gesamte Tabelle als einzelnes Fenster“. Nützlich für Berechnungen wie „Prozentsatz der Gesamtmenge“.

Ranking-Funktionen

SQL
ROW_NUMBER() OVER (PARTITION BY p ORDER BY o)
RANK()       OVER (PARTITION BY p ORDER BY o)
DENSE_RANK() OVER (PARTITION BY p ORDER BY o)

Unterschiede (mit Werten 100, 100, 90, 80):

FunktionPositionen
ROW_NUMBER1, 2, 3, 4 (immer eindeutig)
RANK1, 1, 3, 4 (Gleichstände teilen sich eine Position, hinterlässt „Lücken“)
DENSE_RANK1, 1, 2, 3 (Gleichstände teilen sich eine Position, ohne Lücken)

Beispiel: Produktranking pro Kategorie

SQL
SELECT name,
       category_id,
       price,
       RANK() OVER (PARTITION BY category_id ORDER BY price DESC) AS rank
FROM   products
ORDER BY category_id, rank;

Für jeden category_id beginnt der RANK bei 1 neu und sortiert in absteigender Reihenfolge Preis: Sie erhalten die Rangfolge der Produkte innerhalb jeder Kategorie in einer einzigen Kategorie Schuss.

Fortlaufende Nummerierung

SQL
-- Progressive order number for each customer:
SELECT id,
       customer_id,
       ordered_at,
       ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY ordered_at) AS row_num
FROM   orders
ORDER BY customer_id, row_num;

Die erste Bestellung jedes Kunden hat row_num = 1, die zweite 2 usw.

Probieren Sie es aus

Übung#sql.m7.l2.e1
Versuche: 0Wird geladen…

Zeigen Sie für jedes Produkt den Namen, die Kategorie-ID, den Preis und den Rang an (die Rangfolge nach absteigendem Preis INNERHALB der Kategorie; verwenden Sie RANK). Sortieren Sie nach aufsteigender Kategorie-ID und aufsteigendem Rang.

Editor wird geladen…
Hinweis anzeigen

PARTITION NACH Kategorie_ID-Gruppen, ORDER NACH Preis DESC Bestellungen innerhalb der Gruppe.

Lösung nach 3 Versuchen verfügbar

Wiederholungsübung

Übung#sql.m7.l2.e2
Versuche: 0Wird geladen…

Zeigen Sie für jede Bestellung die ID, die Kunden-ID, die Bestellnummer und die Zeilennummer an (progressive ROW_NUMBER pro Kunde, sortiert nach aufsteigender Bestellnummer). Sortieren Sie nach customer_id und row_num.

Editor wird geladen…
Hinweis anzeigen

ROW_NUMBER ist innerhalb der Partition immer eindeutig.

Lösung nach 3 Versuchen verfügbar