This lesson on SQL Screen Drills (Timed Sets) is hands-on and example-driven. You will master the application of ROW_NUMBER, RANK, and DENSE_RANK to solve common SQL interview problems. You will learn how to choose the correct ranking function based on whether duplicates are allowed and if rank gaps are necessary. This knowledge will enable you to efficiently find Nth highest values, top positions, and the latest records per group.
What You'll Be Able To Do
- Select the appropriate window function (RANK, DENSE_RANK, ROW_NUMBER) for a given ranking requirement.
- Write a query to find the Nth highest value using DENSE_RANK.
- Apply the PARTITION BY clause to rank data within specific groups (e.g., departments or customers).
- Differentiate between finding "top N positions" and "top N values" in a dataset.
- Construct an outer query to filter results generated by a window function.
Topics Covered in SQL Screen Drills (Timed Sets)
- Ranking Function Rules (0:00 - 0:30) — The three ranking functions are defined based on uniqueness and gap behavior.
- Top Three Positions (RANK) (0:30 - 2:30) — Finding top three positions requires RANK because ties are allowed and subsequent ranks must be skipped.
- Nth Highest Salary (DENSE_RANK) (2:30 - 4:45) — Finding the Nth highest salary requires DENSE_RANK because rank numbers cannot be skipped.
- Highest Salary per Dept (PARTITION BY) (4:45 - 7:00) — Ranking within groups is achieved using PARTITION BY, and filtering for rank 1 works with both RANK and DENSE_RANK.
- Latest Record per Group (ROW_NUMBER) (7:00 - 8:30) — Finding exactly one record per group, like the latest order, is best solved using ROW_NUMBER.
- Top N Values (DENSE_RANK) (8:30 - 10:00) — Finding the top N values where ties are allowed and gaps are forbidden requires DENSE_RANK.
- Decision Logic Summary (10:00 - 10:45) — Always ask if duplicates are possible and if ranks should be skipped to choose the correct function.
SQL Cheat Sheet
-
ROW_NUMBER() OVER (PARTITION BY <col> ORDER BY <col>)— Assigns a unique, sequential number to each row within a partitionROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date DESC) -
RANK() OVER (ORDER BY <col> DESC)— Assigns rank; allows duplicates but skips subsequent numbers (gaps)RANK() OVER (ORDER BY salary DESC) -
DENSE_RANK() OVER (ORDER BY <col> DESC)— Assigns rank; allows duplicates and does not skip subsequent numbers (no gaps)DENSE_RANK() OVER (ORDER BY revenue DESC) -
PARTITION BY <col>— Divides the result set into groups before applying the window functionRANK() OVER (PARTITION BY department ORDER BY salary DESC) -
Outer Query Filtering— Filters the results of a window function applied in an inner querySELECT * FROM (SELECT employee, RANK() OVER (...) AS rk FROM employee) AS sub WHERE sub.rk <= 3; -
RANK() = 1 vs DENSE_RANK() = 1— Both functions yield identical results when filtering only for rank oneWHERE rank = 1
Comparison Table
| Function | Allows Duplicates (Ties) | Gaps in Sequence |
|---|---|---|
| ROW_NUMBER | No (always unique) | No (always sequential) |
| RANK | Yes | Yes (skips numbers) |
| DENSE_RANK | Yes | No (no gaps) |
Common Pitfalls
- Mistake: Using RANK when finding the Nth highest salary. Avoid: Use DENSE_RANK to ensure no ranks are skipped, finding the true Nth value.
- Mistake: Trying to filter a window function directly in the WHERE clause. Avoid: Always wrap the window function query in a subquery and filter the outer query.
- Mistake: Confusing "top N positions" with "top N values.". Avoid: "Positions" implies using RANK (gaps); "values" implies using DENSE_RANK (no gaps).
- Mistake: Using RANK or DENSE_RANK when only one record per group is needed. Avoid: Use ROW_NUMBER for guaranteed unique results per partition.
- Mistake: Forgetting ORDER BY inside the window function. Avoid: Always specify ORDER BY to define the criteria for the ranking calculation.
FAQs
- Why can't I filter the window function result directly using WHERE? Window functions are calculated after the WHERE clause executes. You must use an outer query or CTE to filter the results based on the calculated rank.
- When finding the highest salary in each department, why do RANK and DENSE_RANK give the same result? When filtering specifically for rank 1, duplicates are handled identically. The question of skipping subsequent ranks becomes irrelevant.
- What does the keyword "position" imply in an interview question? "Position" suggests that if two people tie, the next position should be skipped. This indicates the use of the RANK function.
- When should I use ROW_NUMBER? Use ROW_NUMBER when you need exactly one unique record per group, such as finding the latest order for each customer.