sqlcmd.net validated sql reference
advanced windowing MySQL MariaDB SQL Server PostgreSQL SQLite

Access Previous And Next Rows With LAG And LEAD

Reference values from preceding or following rows within an ordered partition without writing a self-join.

Docker-validated Not currently validation-green

Calculate the day-over-day revenue change for each date in a sales log

The first row has no preceding row so prev_revenue and revenue_change are NULL. Each subsequent row subtracts the previous day's revenue from the current day's. Jan 3 shows a drop of 30 (120 − 150 = −30). No PARTITION BY is used because all rows belong to a single series.

Rows loaded before the example query runs.
Setup
CREATE TABLE sales (id INT, sale_date VARCHAR(10), revenue INT);

INSERT INTO
  sales (id, sale_date, revenue)
VALUES
  (1, '2024-01-01', 100),
  (2, '2024-01-02', 150),
  (3, '2024-01-03', 120),
  (4, '2024-01-04', 200);
Shared across supported engines.
SQL
SELECT
  sale_date,
  revenue,
  LAG (revenue) OVER (
    ORDER BY
      sale_date
  ) AS prev_revenue,
  revenue - LAG (revenue) OVER (
    ORDER BY
      sale_date
  ) AS revenue_change
FROM
  sales
ORDER BY
  sale_date;
Returned rows for the shared example.
sale_daterevenueprev_revenuerevenue_change
2024-01-01100NULLNULL
2024-01-0215010050
2024-01-03120150-30
2024-01-0420012080

Output is identical across all supported engine versions.

Where this command helps.

  • comparing each row with the previous or next event
  • calculating period-over-period change without a self-join

What the command is doing.

LAG(column) returns the value of a column from the previous row in the defined window order. LEAD(column) returns the value from the next row. Both accept an optional offset (default 1) and a default value to return when no preceding or following row exists. They are the idiomatic way to compute period-over-period changes such as day-over-day revenue differences.