BBampaa

Lessons › SQL › Chapter 6: Window Functions

SQL lesson

LAG() and LEAD()

LAG() and LEAD() are window functions - meaning they look across neighboring rows without collapsing the results - that pull a value from the row before or after the current one into the same row.

Try this lesson free →
About 5–10 minutes · no sign-up needed

Example

Comparing Retail Orders with LAG() and LEAD()

SELECT order_id, customer_id, order_date, revenue,
       LAG(revenue, 1, 0) OVER (PARTITION BY customer_id ORDER BY order_date) AS prev_order_revenue,
       LEAD(revenue, 1, 0) OVER (PARTITION BY customer_id ORDER BY order_date) AS next_order_revenue
FROM orders
ORDER BY customer_id, order_date

Result:

order_idcustomer_idorder_daterevenueprev_order_revenuenext_order_revenue
O2001C1012024-01-05120.0095.5
O2002C1012024-02-1495.5120.0210.75
O2003C1012024-03-22210.7595.5180.0
O2004C1012024-04-30180.0210.75340.25
O2005C1012024-05-18340.25180.00

Step by step

  1. AS gives a column a friendlier name in the result.
    SELECT order_id, customer_id, order_date, revenue,
           LAG(revenue, 1, 0) OVER (PARTITION BY customer_id ORDER BY order_date) AS prev_order_revenue,
           LEAD(revenue, 1, 0) OVER (PARTITION BY customer_id ORDER BY order_date) AS next_order_revenue
  2. FROM tells SQL which table to pull the data from.
    SELECT order_id, customer_id, order_date, revenue,
           LAG(revenue, 1, 0) OVER (PARTITION BY customer_id ORDER BY order_date) AS prev_order_revenue,
           LEAD(revenue, 1, 0) OVER (PARTITION BY customer_id ORDER BY order_date) AS next_order_revenue
    FROM orders
  3. ORDER BY puts the rows in your chosen order.
    SELECT order_id, customer_id, order_date, revenue,
           LAG(revenue, 1, 0) OVER (PARTITION BY customer_id ORDER BY order_date) AS prev_order_revenue,
           LEAD(revenue, 1, 0) OVER (PARTITION BY customer_id ORDER BY order_date) AS next_order_revenue
    FROM orders
    ORDER BY customer_id, order_date;

Practice

Try each one in your head first, then open the answer.

1. Using orders, write a query that adds the previous row's revenue value to each row, ordered by order_date.
SELECT *, LAG(revenue) OVER (ORDER BY order_date) FROM orders
2. Using store_sales, write a query that adds the next row's revenue value to each row, ordered by sale_date.
SELECT *, LEAD(revenue) OVER (ORDER BY sale_date) FROM store_sales
3. Using products, write a query that adds the previous row's price value to each row, ordered by price.
SELECT *, LAG(price) OVER (ORDER BY price) FROM products
4. Using employees, write a query that adds the next row's salary value to each row, ordered by hire_date.
SELECT *, LEAD(salary) OVER (ORDER BY hire_date) FROM employees
5. Using reviews, write a query that adds the previous row's rating value to each row, ordered by review_date.
SELECT *, LAG(rating) OVER (ORDER BY review_date) FROM reviews

Learn it by doing. This lesson is a short hands-on level on Bampaa: see it work, then build and write it yourself, with instant feedback.

Try this lesson free →
About 5–10 minutes · no sign-up needed