The growth team wants to find win-back orders: orders placed more than 7 days after the same customer's previous order.
From food_orders, return customer_id, order_id, order_date, prev_order_date and days_since_prev for every such order. A customer's first order has no previous order and must not appear. Order by customer_id, then order_date.
Sample data
Table: food_orders
14 row(s) · showing first 8
| order_idINT | customer_idINT | order_dateDATE |
|---|---|---|
| 1 | 1 | 2026-09-01 |
| 2 | 1 | 2026-09-04 |
| 3 | 1 | 2026-09-20 |
| 4 | 1 | 2026-09-22 |
| 5 | 2 | 2026-09-02 |
| 6 | 2 | 2026-09-18 |
| 7 | 2 | 2026-10-05 |
| 14 | 2 | 2026-10-06 |
food_orders
- order_idINT
- customer_idINT
- order_dateDATE
- Step 1: `LAG(order_date)` looks one row back inside each customer (`PARTITION BY customer_id`) after sorting by date.
- Step 2: Window functions cannot be used in `WHERE`, so compute the previous date in a CTE and filter in the outer query.
- Step 3: Subtracting two `DATE` values in PostgreSQL returns a whole number of days. For a first order `prev_order_date` is NULL, so the comparison is unknown and the row is dropped automatically.
WITH gaps AS (
SELECT customer_id,
order_id,
order_date,
LAG(order_date) OVER (
PARTITION BY customer_id
ORDER BY order_date, order_id
) AS prev_order_date
FROM food_orders
)
SELECT customer_id,
order_id,
order_date,
prev_order_date,
order_date - prev_order_date AS days_since_prev
FROM gaps
WHERE order_date - prev_order_date > 7
ORDER BY customer_id, order_date;More Window Functions questions
Practising alone only goes so far — our live cohorts pair SQL depth with dashboards, agentic analytics projects and mock interviews.
Explore the program