Window functions
1711 min
GROUP BY folds rows into one. Window functions leave every row in place and add a calculation over its group next to it: a rank, a running total, the value from the previous row.
The pattern
function() OVER (PARTITION BY group ORDER BY order)PARTITION BY— which groups to calculate within (without it, the whole result is one group);ORDER BY— the order inside each group.
Ranks: ROW_NUMBER, RANK, DENSE_RANK
ROW_NUMBER— 1, 2, 3… even equal values get different numbers;RANK— equal values share a rank and the next one skips (1, 1, 3);DENSE_RANK— equal values share a rank with no gap (1, 1, 2).
Within each group
The best-paid teacher of every faculty:
A window function cannot be used in WHERE, so we calculate it in a CTE first and filter afterwards.
Aggregate + OVER: shares and running totals
SUM(...) OVER () is the total of the whole result, shown next to every row.
A running total of revenue by month:
LAG and LEAD — the neighbouring row
LAG(x) is the value from the previous row and LEAD(x) from the next one. Change compared with the previous month:
Show each employee’s first_name, last_name, salary and their salary rank across the whole company (DENSE_RANK, highest = 1), by rank ascending.
Show each student’s id, first_name and their position within their own group: whoever enrolled first (enrolled_at) is first, and on the same date the smaller id comes first (ROW_NUMBER, PARTITION BY group_id).
Remember
- A window function does not fold rows — it adds a calculation to each row.
PARTITION BYis the group,ORDER BYis the order.- To filter on the result, wrap it in a CTE or subquery first.