LAG

LAG(expr, N, default) OVER ([PARTITION BY …] ORDER BY …)

Gibt den Wert eines Ausdrucks aus der Zeile N Zeilen weiter oben (standardmäßig 1) nach der Reihenfolge in OVER zurück. Für die erste Zeile gibt sie den Standardwert zurück, sonst NULL.

Parameter

  • expr – der Wert, der aus der vorherigen Zeile gelesen wird.
  • N – optional, wie viele Zeilen zurück. Standard ist 1.
  • default – optional, der Wert, wenn es keine vorherige Zeile gibt. MySQL unterstützt ihn, MariaDB (geprüft in den Versionen 10.4 und 10.11) lehnt ihn mit einem Syntaxfehler ab – portabel IFNULL(LAG(…) OVER (…), default).

Beispiele

Die Beispiele mit den Tabellen customers, products und orders verwenden die Beispieldatenbank aus der Serie SQL-Grundlagen.

Wie viele Tage seit der vorherigen Bestellung desselben Kunden vergangen sind:

SELECT customer_id, order_date,
  LAG(order_date) OVER (PARTITION BY customer_id ORDER BY order_date, id) AS previous,
  DATEDIFF(order_date, LAG(order_date) OVER (PARTITION BY customer_id ORDER BY order_date, id)) AS days
FROM orders
WHERE customer_id IN (1, 2)
ORDER BY customer_id, order_date, id;
+-------------+------------+------------+------+
| customer_id | order_date | previous   | days |
+-------------+------------+------------+------+
|           1 | 2026-01-05 | NULL       | NULL |
|           1 | 2026-01-05 | 2026-01-05 |    0 |
|           1 | 2026-02-20 | 2026-01-05 |   46 |
|           2 | 2026-01-12 | NULL       | NULL |
|           2 | 2026-03-15 | 2026-01-12 |   62 |
+-------------+------------+------------+------+

Umsatz nach Monaten und die Änderung gegenüber dem Vormonat:

SELECT month_key, revenue, revenue - IFNULL(LAG(revenue) OVER (ORDER BY month_key), 0) AS difference
FROM (
  SELECT EXTRACT(YEAR_MONTH FROM o.order_date) AS month_key, SUM(o.quantity * p.price) AS revenue
  FROM orders o JOIN products p ON p.id = o.product_id
  GROUP BY month_key
) x
ORDER BY month_key;
+-----------+---------+------------+
| month_key | revenue | difference |
+-----------+---------+------------+
|    202601 |  110.80 |     110.80 |
|    202602 |   19.60 |     -91.20 |
|    202603 |   71.60 |      52.00 |
+-----------+---------+------------+

Worauf Sie achten sollten

  • Ohne Standardwert ist das Ergebnis für die erste Zeile NULL und die Differenz damit ebenfalls NULL – daher IFNULL() im Beispiel.
  • Die Reihenfolge in OVER (ORDER BY) ist etwas anderes als die Reihenfolge des Ergebnisses – setzen Sie beide, damit die Ausgabe Sinn ergibt.
  • Fensterfunktionen gibt es in MySQL ab Version 8.0 und in MariaDB ab 10.2. Das ältere MySQL 5.7 hat sie nicht.

Siehe auch:
LEAD()
OVER
DATEDIFF()