Ranking and top N per group
In this lesson1 sections
In a live SQL round, "top N per group" is the window-function question you are most likely to get, and the follow-up is nearly always about ties: "what if two of them are equal?" This lesson shows how to choose between ROW_NUMBER, RANK and DENSE_RANK on purpose, return the top N rows inside each group, read "the Nth value" correctly when values repeat, pull the latest row per key, and make each answer come out the same on every run.
Three ways to number tied rows
A window function computes a value for each row from a set of related rows, its window, without collapsing those rows into one the way GROUP BY does. Three window functions number rows in the order you give them:
ROW_NUMBER()numbers 1, 2, 3, 4 with no repeats, even when rows tie.RANK()gives tied rows the same number, then skips: 1, 2, 2, 4.DENSE_RANK()gives tied rows the same number and does not skip: 1, 2, 2, 3.
The examples use a running club's Saturday 5K. The table results has one row per runner per Saturday, with the finish time in seconds (lower is better):
| run_date | runner | finish_seconds |
|---|---|---|
| 2026-02-28 | Ana | 1310 |
| 2026-02-28 | Ben | 1290 |
| 2026-02-28 | Dev | 1350 |
| 2026-03-07 | Ana | 1290 |
| 2026-03-07 | Ben | 1305 |
| 2026-03-07 | Caro | 1305 |
| 2026-03-07 | Dev | 1340 |
| 2026-03-14 | Ana | 1290 |
| 2026-03-14 | Ben | 1305 |
| 2026-03-14 | Caro | 1299 |
Here is the 7 March run, numbered all three ways. With no PARTITION BY, the window is every row left after WHERE, here the four runners of 7 March.
The rest of this lesson is for Premium members
Premium opens every lesson in this course, along with all questions and solutions on PracHub.