LEAD und LAG: Zugriff auf vorherige/nächste Zeilen

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.

Lead und Lag

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.