Wenn du in SQL arbeitest, stößt du früher oder später auf eine typische Herausforderung: Du möchtest eine Zeile mit der vorherigen oder nächsten Zeile vergleichen. Genau hier kommen die Fensterfunktionen LEAD und LAG ins Spiel.
Gerade in der Analyse von Zeitreihen, Umsatzentwicklungen oder Log-Daten sind solche Vergleiche extrem häufig. Ohne LEAD und LAG müsstest du oft auf komplexe Selbst-JOINs zurückgreifen, was Abfragen schnell unübersichtlich und schwer wartbar macht.
Problem: Vergleich mit vorheriger/nächster Zeile ohne Selbst-Join
Angenommen, du hast eine Tabelle mit Monatsumsätzen und möchtest die Veränderung zum Vormonat berechnen. Klassisch würde man das oft mit einem Self-Join lösen:
SELECT
a.monat,
a.umsatz,
b.umsatz AS umsatz_vormonat
FROM umsaetze a
JOIN umsaetze b
ON b.monat = DATEADD(month, -1, a.monat);
Das funktioniert, ist aber:
- schwer lesbar
- fehleranfällig bei Lücken in Daten
- oft nicht optimal performant
Lösung: Fensterfunktionen LEAD und LAG
Mit den Fensterfunktionen LEAD und LAG wird diese Logik deutlich einfacher und lesbarer. Sie ermöglichen dir, direkt auf vorherige oder nächste Zeilen innerhalb einer definierten Sortierung zuzugreifen – ohne Joins.
Ein Beispiel mit LAG:
SELECT
monat,
umsatz,
LAG(umsatz) OVER (ORDER BY monat) AS umsatz_vormonat
FROM umsaetze;
Damit bekommst du den Wert der vorherigen Zeile direkt in derselben Abfrage.
Auch im Kontext verschiedener SQL Datenbanktypen – insbesondere relationaler Datenbanken wie PostgreSQL oder MySQL sowie analytischer Datenbanksysteme – sind Fensterfunktionen heute ein zentraler Bestandteil moderner SQL-Analysen.
Im nächsten Abschnitt schauen wir uns die Grundlagen und Syntax von LEAD und LAG genauer an.
Grundlagen: Syntax von LEAD und LAG
Um LEAD und LAG effektiv zu nutzen, solltest du zuerst die grundlegende Syntax verstehen.
Beide Funktionen gehören zu den Fensterfunktionen und arbeiten immer in Kombination mit OVER.
Grundlegende Syntax
LEAD:
LEAD(spalte, offset, default) OVER (
PARTITION BY ...
ORDER BY ...
)
LAG funktioniert analog:
LAG(spalte, offset, default) OVER (
PARTITION BY ...
ORDER BY ...
)
Bedeutung der Parameter
- spalte: Die Spalte, deren Wert du aus der vorherigen oder nächsten Zeile abrufen möchtest.
- offset: Gibt an, wie viele Zeilen vor oder zurück geschaut wird (Standard: 1).
- default: Optionaler Wert, der zurückgegeben wird, wenn kein vorheriger oder nächster Wert existiert (z. B. am Anfang oder Ende der Daten).
Die Rolle von OVER
Der OVER-Teil definiert, wie die Daten betrachtet werden:
- ORDER BY: Bestimmt die Reihenfolge der Zeilen – absolut entscheidend für LEAD und LAG.
- PARTITION BY (optional): Teilt die Daten in Gruppen auf, innerhalb derer die Berechnung separat erfolgt.
Ohne ein korrektes ORDER BY wäre nicht definiert, was „vorherige“ oder „nächste“ Zeile bedeutet.
Im nächsten Schritt schauen wir uns einfache Beispiele an, damit du siehst, wie LEAD und LAG in der Praxis funktionieren.
Einfache Beispiele für LEAD und LAG
Nachdem du die Syntax kennst, schauen wir uns jetzt einfache, praxisnahe Beispiele an. So verstehst du schnell, wie LEAD und LAG in echten Abfragen funktionieren.
Zugriff auf vorherige Zeile mit LAG
Mit LAG kannst du auf den Wert der vorherigen Zeile zugreifen. Das ist besonders nützlich, wenn du Entwicklungen oder Veränderungen analysieren möchtest.
SELECT
monat,
umsatz,
LAG(umsatz) OVER (ORDER BY monat) AS umsatz_vormonat
FROM umsaetze;
Ergebnis: Jede Zeile enthält zusätzlich den Umsatz des vorherigen Monats.
Zugriff auf nächste Zeile mit LEAD
LEAD funktioniert genau umgekehrt und greift auf die nächste Zeile zu. Das ist z. B. hilfreich, wenn du zukünftige Werte vergleichen oder Prognosen vorbereiten möchtest.
SELECT
monat,
umsatz,
LEAD(umsatz) OVER (ORDER BY monat) AS umsatz_naechster_monat
FROM umsaetze;
Ergebnis: Jede Zeile enthält zusätzlich den Umsatz des folgenden Monats.
Differenz zur vorherigen Zeile berechnen
Eine sehr häufige Anwendung ist die Berechnung der Veränderung zum vorherigen Wert.
SELECT
monat,
umsatz,
umsatz - LAG(umsatz) OVER (ORDER BY monat) AS veraenderung
FROM umsaetze;
Damit kannst du direkt sehen, ob der Umsatz gestiegen oder gefallen ist.
Diese einfachen Beispiele bilden die Grundlage für viele analytische Auswertungen in SQL – besonders wenn du mit verschiedenen SQL Datenbanktypen arbeitest, in denen Zeitreihenanalysen eine wichtige Rolle spielen.
Im nächsten Abschnitt gehen wir auf praktische Anwendungsfälle im Alltag ein.
Praktische Anwendungsfälle
LEAD und LAG sind nicht nur theoretische Funktionen – sie werden in der Praxis sehr häufig eingesetzt, besonders in der Datenanalyse und im Reporting.
Monatsvergleiche (Umsatzänderung zum Vormonat)
Einer der häufigsten Anwendungsfälle ist der Vergleich von Werten über die Zeit, zum Beispiel Umsatzänderungen.
SELECT
monat,
umsatz,
umsatz - LAG(umsatz) OVER (ORDER BY monat) AS differenz_zum_vormonat
FROM umsaetze;
Damit erkennst du sofort, wie sich der Umsatz von Monat zu Monat verändert hat.
Vorjahreswerte in derselben Zeile
Auch Jahresvergleiche lassen sich elegant umsetzen, wenn deine Daten entsprechend sortiert sind.
Typisch ist hier die Kombination mit PARTITION BY, um z. B. nach Produkt oder Kategorie zu gruppieren.
SELECT
jahr,
umsatz,
LAG(umsatz) OVER (ORDER BY jahr) AS umsatz_vorjahr
FROM umsaetze_jahr;
Erkennung von Trends (steigend oder fallend)
Mit LAG kannst du sehr einfach Trends erkennen, indem du aktuelle und vorherige Werte vergleichst.
SELECT
monat,
umsatz,
CASE
WHEN umsatz > LAG(umsatz) OVER (ORDER BY monat) THEN 'steigend'
WHEN umsatz < LAG(umsatz) OVER (ORDER BY monat) THEN 'fallend'
ELSE 'gleich'
END AS trend
FROM umsaetze;
Das ist besonders hilfreich für Dashboards und automatisierte Reports.
Füllen von Lücken (z. B. fehlende Werte mit Vorgänger)
In realen Daten gibt es oft fehlende Werte. Mit LAG kannst du diese teilweise sinnvoll auffüllen.
SELECT
datum,
COALESCE(umsatz, LAG(umsatz) OVER (ORDER BY datum)) AS gefuellter_umsatz
FROM umsaetze;
So kannst du fehlende Werte durch den zuletzt bekannten Wert ersetzen.
Diese Anwendungsfälle zeigen, warum Fensterfunktionen ein zentraler Bestandteil moderner SQL-Analysen sind. Besonders bei unterschiedlichen SQL Datenbanktypen wie relationalen und analytischen Systemen gehören sie heute zum Standardwerkzeug für Data Analysts und Entwickler.
Im nächsten Abschnitt schauen wir uns an, wie LEAD und LAG mit PARTITION BY kombiniert werden.
LEAD und LAG mit PARTITION BY
Bis jetzt hast du LEAD und LAG auf eine komplette Tabelle angewendet.
In der Praxis möchtest du Daten aber oft in Gruppen auswerten – genau dafür gibt es PARTITION BY.
Gruppierte Berechnungen (z. B. pro Produktkategorie)
Mit PARTITION BY teilst du deine Daten in logische Gruppen auf.
Innerhalb jeder Gruppe wird die Fensterfunktion separat berechnet.
SELECT
kategorie,
monat,
umsatz,
LAG(umsatz) OVER (
PARTITION BY kategorie
ORDER BY monat
) AS umsatz_vormonat
FROM umsaetze;
Ergebnis: Für jede Produktkategorie wird der Umsatz mit dem vorherigen Monat innerhalb derselben Kategorie verglichen.
Beispiel: Entwicklung pro Produkt
Besonders nützlich ist das bei Detailanalysen pro Produkt oder Kundengruppe. So vermeidest du, dass Werte verschiedener Gruppen miteinander vermischt werden.
SELECT
produkt_id,
datum,
umsatz,
LEAD(umsatz) OVER (
PARTITION BY produkt_id
ORDER BY datum
) AS naechster_umsatz
FROM umsaetze;
Warum PARTITION BY so wichtig ist
Ohne PARTITION BY würde die Funktion über die gesamte Tabelle hinweg rechnen.
Das führt oft zu falschen Ergebnissen, wenn mehrere Entitäten (z. B. Produkte, Kunden oder Standorte) in einer Tabelle enthalten sind.
- Saubere Trennung von Daten je Gruppe
- Korrekte zeitliche Vergleiche innerhalb einer Dimension
- Wichtige Grundlage für Reporting und BI-Systeme
Gerade in komplexeren Datenmodellen, unabhängig von den verwendeten SQL Datenbanktypen,
ist PARTITION BY entscheidend, um aussagekräftige Analysen zu erstellen.
Im nächsten Abschnitt schauen wir uns typische Fehler und Best Practices im Umgang mit LEAD und LAG an.
Unterschiede zwischen LEAD/LAG und anderen Fensterfunktionen
LEAD und LAG sind speziell dafür gemacht, auf vorherige oder nächste Zeilen zuzugreifen. In SQL gibt es aber noch weitere Fensterfunktionen, die auf den ersten Blick ähnlich wirken, jedoch andere Aufgaben erfüllen.
LEAD/LAG im Vergleich zu ROW_NUMBER
ROW_NUMBER() vergibt eine laufende Nummer innerhalb einer Partition, basierend auf einer Sortierung.
Anders als LEAD oder LAG greift diese Funktion nicht auf andere Zeilenwerte zu, sondern erzeugt lediglich eine Position.
SELECT
monat,
umsatz,
ROW_NUMBER() OVER (ORDER BY monat) AS zeilennummer
FROM umsaetze;
Während du mit LAG den Wert des vorherigen Monats bekommst, bekommst du hier nur eine Indexnummer.
LEAD/LAG vs. FIRST_VALUE und LAST_VALUE
FIRST_VALUE() und LAST_VALUE() greifen auf den ersten bzw. letzten Wert einer Partition zu.
Diese Funktionen sind besonders nützlich, wenn du Referenzwerte innerhalb einer Gruppe brauchst.
SELECT
kategorie,
umsatz,
FIRST_VALUE(umsatz) OVER (
PARTITION BY kategorie
ORDER BY monat
) AS startwert
FROM umsaetze;
Im Gegensatz dazu bewegen sich LEAD und LAG immer relativ zur aktuellen Zeile.
Wann du welche Funktion nutzt
- LAG: Vergleich mit vorherigen Werten (z. B. Vormonat)
- LEAD: Vergleich mit zukünftigen Werten (z. B. Prognosen)
- ROW_NUMBER: Nummerierung von Zeilen
- FIRST_VALUE / LAST_VALUE: Referenzwerte innerhalb einer Gruppe
Diese Unterscheidung ist wichtig, um effiziente und korrekte Analysen zu erstellen – unabhängig von den verwendeten SQL Datenbanktypen.
Im letzten Abschnitt fassen wir zusammen, wann du LEAD und LAG sinnvoll einsetzen solltest.
Fazit: Wann du LEAD und LAG einsetzen solltest
LEAD und LAG gehören zu den wichtigsten Fensterfunktionen in SQL, wenn es um zeitbasierte
Analysen und den Vergleich von Zeilen geht. Sie ersetzen komplexe Self-JOINs durch eine deutlich lesbarere und
wartungsfreundlichere Lösung.
Immer wenn du Werte zwischen benachbarten Zeilen vergleichen möchtest – sei es für Trends, Veränderungen oder
Zeitreihenanalysen – sind diese Funktionen die richtige Wahl.
Wichtige Einsatzszenarien im Überblick
- Vergleich von aktuellen und vorherigen Werten (z. B. Umsatzentwicklung)
- Analyse von zukünftigen Werten (z. B. Vorhersagen mit LEAD)
- Erkennung von Trends und Mustern in Datenreihen
- Arbeiten mit gruppierten Daten über
PARTITION BY
Warum LEAD und LAG so wichtig sind
Besonders in modernen Datenarchitekturen spielen saubere und effiziente Abfragen eine zentrale Rolle.
Unabhängig davon, mit welchen SQL Datenbanktypen du arbeitest – ob relationale Systeme wie PostgreSQL
oder analytische Plattformen – Fensterfunktionen gehören heute zum Standardwerkzeug für Datenanalysten und Entwickler.
Sie helfen dir dabei, komplexe Logik verständlich abzubilden und gleichzeitig die Performance und Wartbarkeit deiner
SQL-Abfragen zu verbessern.
Abschließender Gedanke
Wenn du beginnst, LEAD und LAG regelmäßig zu nutzen, wirst du schnell feststellen,
dass viele klassische Self-JOIN-Lösungen überflüssig werden. Deine SQL-Abfragen werden kürzer, klarer und näher an der
eigentlichen Fragestellung.
Von SQL zu Power BI/Tableau – so funktioniert der Datenfluss
In der modernen Datenanalyse spielen SQL und BI-Tools wie Power...
Artikel lesenEinsteiger-Guide zu PostgreSQL: Warum und wie du mit SQL in PostgreSQL startest
PostgreSQL ist eine der beliebtesten und leistungsstärksten Open-Source-Datenbanken weltweit. Für...
Artikel lesenIndexes verstehen: Warum manche Queries ewig dauern und andere nicht
Hattest du jemals eine SQL-Query, die mal in Millisekunden und...
Artikel lesenWas ist SQL? Einfach erklärt!
Stell dir vor, du könntest mit ein paar einfachen Befehlen...
Artikel lesen