Data Analyst & Analytics Interview · SQL for Analysts · Lesson 2 of 3
Window functions & CTEs
Window functions compute across a set of rows related to the current row without collapsing them — the tool that separates a fluent analyst from a beginner. CTEs (WITH clauses) name intermediate steps so complex logic reads top-to-bottom.
- Ranking:
ROW_NUMBER()(unique 1..n),RANK()(ties share a rank, leaves gaps),DENSE_RANK()(ties share, no gaps). - Offset:
LAG()/LEAD()reach the previous/next row — month-over-month deltas, retention. - Running totals / moving averages: aggregates with an
OVER (... ORDER BY ...)frame. - The
PARTITION BYclause is a per-window GROUP BY;ORDER BYinsideOVERdefines sequence.
-- Each customer's orders ranked newest-first, plus days since prior order WITH ranked AS ( SELECT customer_id, order_date, amount, ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date DESC) AS rn, order_date - LAG(order_date) OVER ( PARTITION BY customer_id ORDER BY order_date ) AS days_since_prev FROM orders ) SELECT * FROM ranked WHERE rn = 1; -- most recent order per customer
Top-N-per-groupThe 'top order / latest event per customer' question is a window-function tell.
ROW_NUMBER() OVER (PARTITION BY id ORDER BY ...) then filter rn = 1. Doing it with a correlated subquery works but signals you don't know windows.You can't filter a window in WHEREWindow functions are computed after
WHERE/GROUP BY, so you cannot reference rn in the same query's WHERE. Wrap it in a CTE or subquery and filter in the outer query.◆ Lock it in
- Window functions summarize across related rows without collapsing them.
ROW_NUMBER/RANK/DENSE_RANK,LAG/LEAD, and running aggregates are the core kit.- Filter a window result in an outer query (CTE/subquery) — never the same WHERE.
Feynman drill — say it out loudExplain the difference between RANK and DENSE_RANK, and why you must wrap ROW_NUMBER in a CTE to filter on it.
Step 1 rate your confidence · Step 2 pick your answer
Three rows tie for the top value. Which function assigns them rank 1, 1, 1 and gives the next row rank 2?
Step 1 — how sure are you?