Skip to content
>_sqlbuddy

Guide

SQL Window Functions: The Complete Guide

Learn ROW_NUMBER, RANK, DENSE_RANK, LAG, LEAD, and aggregate windows with worked SQL interview examples, frame definitions, and the mistakes that fail interviews.

What is a window function?

A window function computes a value across a set of rows that are related to the current row — the 'window' — without collapsing those rows into one output row. Unlike GROUP BY, which produces one row per group, a window function keeps every input row and adds a computed column.

The syntax is function_name() OVER (PARTITION BY ... ORDER BY ...). PARTITION BY splits rows into groups, ORDER BY orders rows within each group, and the optional frame clause (ROWS BETWEEN ... AND ...) narrows the window further.

The four families of window functions

Ranking: ROW_NUMBER gives every row a unique number, RANK shares a number across ties but leaves gaps, DENSE_RANK shares ties with no gaps. Use ROW_NUMBER for 'pick one row per group', RANK or DENSE_RANK for 'top N with ties'.

Offset: LAG(col, n) reads n rows back, LEAD(col, n) reads n rows ahead. These power previous/next row comparisons such as rising temperature or gaps between orders.

Aggregate windows: SUM, AVG, MIN, MAX over a window produce running totals and rolling averages when combined with an ORDER BY and frame.

Distribution and navigation: FIRST_VALUE, LAST_VALUE, NTILE, and PERCENT_RANK are less common but appear in a few questions.

Frames: ROWS BETWEEN and why they matter

The default frame for an aggregate window with ORDER BY is ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW — a running total. For a rolling average you need an explicit bounded frame, e.g. ROWS BETWEEN 6 PRECEDING AND CURRENT ROW for a 7-row average.

Without ORDER BY, the frame is the whole partition, which is what makes SUM(amount) OVER () a percentage-of-total computation.

The number-one mistake: filtering on a window function

Window functions run after WHERE, so you cannot filter on them directly. To keep only rows where rnk = 1 you must wrap the query in a subquery or CTE and filter outside. This pattern — rank first, filter second — is the single most common structure in window-function interview questions.

Practice what you learned

Topics

Frequently asked questions

What is the difference between RANK and DENSE_RANK?
Both assign the same number to tied values. RANK then skips numbers after a tie (1, 1, 3), while DENSE_RANK continues without gaps (1, 1, 2).
Can I use a window function in WHERE?
No — window functions are evaluated after WHERE. Wrap the query in a subquery or CTE and filter on the window result outside.

Keep learning