Window functions
The SQL feature that separates juniors from seniors. Running totals, rankings, lag/lead — without grouping the rows away.
What you'll learn
- ✓ The mental model — "aggregate without collapsing"
- ✓ PARTITION BY, ORDER BY, and frame clauses
- ✓ The 5 ranking and offset functions you'll use weekly
A normal aggregate (SUM, AVG, COUNT) collapses many rows into one.
A window function computes an aggregate over a “window” of rows
without collapsing — every input row gets one output row.
The syntax adds OVER (...) after the function:
SUM(amount) OVER (PARTITION BY user_id ORDER BY date)
Three pieces:
PARTITION BY— split the rows into independent groups (likeGROUP BY, but the rows stay).ORDER BY— order rows within each partition.- The frame — optional; defines which rows around the current row to include.
Try it
The seed schema has orders joined to users and products. Let’s
compute the running total revenue per country:
The same SUM you’ve used before — now scoped to each country and
running through time. No GROUP BY needed, and you get one row per
order.
Rankings — ROW_NUMBER, RANK, DENSE_RANK
The differences:
| Function | What happens on ties |
|---|---|
ROW_NUMBER | Each row gets a unique sequential number (ties broken arbitrarily). |
RANK | Tied rows get the same rank; the next rank skips ahead (1, 2, 2, 4). |
DENSE_RANK | Tied rows get the same rank; next rank doesn’t skip (1, 2, 2, 3). |
Use ROW_NUMBER when you want to deduplicate. Use RANK / DENSE_RANK
when ties should share a position.
LAG and LEAD — the “previous row” superpower
LAG(col) gives the value of col from the previous row (within the
partition, in order). LEAD(col) gives it from the next row. Combine
with date math and you get day-over-day deltas, gap analysis, churn
windows — the bread and butter of analytics.
Top-N per group, the full pattern
The reason for the outer query: window functions are evaluated after the WHERE clause of the same SELECT, so you can’t filter on them inline. Wrap-and-filter is the idiom.
Quick check
✦ Quick check
0/3 answeredFinished the lesson?
Mark it complete to track your progress and keep your streak alive. +20 XP