0
0
SQLquery~10 mins

Top-N per group query in SQL - Step-by-Step Execution

Choose your learning style9 modes available
Concept Flow - Top-N per group query
Start with full table
Partition data by group
Order each group by criteria
Assign row numbers within each group
Filter rows where row number <= N
Return top N rows per group
This flow shows how to get the top N rows for each group by partitioning, ordering, numbering, and filtering.
Execution Sample
SQL
SELECT department, employee, salary
FROM (
  SELECT department, employee, salary,
         ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS rn
  FROM employees
) sub
WHERE rn <= 2;
This query returns the top 2 highest salaries per department from the employees table.
Execution Table
StepRowdepartmentemployeesalaryROW_NUMBER() rnActionOutput Included
11SalesAlice900001Assign rn=1 for highest salary in SalesYes
22SalesBob850002Assign rn=2 for second highest in SalesYes
33SalesCharlie700003Assign rn=3, excluded rn>2No
44HRDiana800001Assign rn=1 for highest salary in HRYes
55HREvan750002Assign rn=2 for second highest in HRYes
66HRFiona600003Assign rn=3, excluded rn>2No
77ITGeorge950001Assign rn=1 for highest salary in ITYes
88ITHannah900002Assign rn=2 for second highest in ITYes
99ITIan850003Assign rn=3, excluded rn>2No
10ExitAll rows processed, filtered to rn <= 2Query ends
💡 Rows with rn > 2 are excluded, so only top 2 salaries per department are returned.
Variable Tracker
VariableStartAfter Row 1After Row 2After Row 3After Row 4After Row 5After Row 6After Row 7After Row 8After Row 9Final
rn (row number per group)N/A1 (Sales)2 (Sales)3 (Sales)1 (HR)2 (HR)3 (HR)1 (IT)2 (IT)3 (IT)Final assigned per row
Key Moments - 2 Insights
Why do some rows have rn values greater than 2 but are not included in the output?
Rows with rn > 2 are filtered out by the WHERE clause (rn <= 2), so only the top 2 rows per group remain, as shown in execution_table rows 3, 6, and 9.
How does the ROW_NUMBER() function know to restart counting for each department?
Because of PARTITION BY department in the window function, ROW_NUMBER() resets to 1 for each new department group, as seen in execution_table steps 4 and 7.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the rn value for employee 'Evan' in the HR department?
A1
B3
C2
DNone
💡 Hint
Check execution_table row 5 under the 'ROW_NUMBER() rn' column.
At which step does the query exclude a row because rn > 2?
AStep 5
BStep 3
CStep 7
DStep 9
💡 Hint
Look for rows marked 'excluded rn>2' in the Action column in execution_table.
If we change rn <= 2 to rn <= 3 in the WHERE clause, how would the output change?
AMore rows per group would be included
BFewer rows per group would be included
CNo change in output
DQuery would error
💡 Hint
Refer to the exit_note and see which rows are currently excluded due to rn > 2.
Concept Snapshot
Top-N per group query syntax:
Use ROW_NUMBER() OVER (PARTITION BY group_col ORDER BY criteria) to number rows per group.
Filter with WHERE rn <= N to get top N rows per group.
This returns the highest (or lowest) N rows per group based on ordering.
Commonly used for ranking or limiting results within groups.
Full Transcript
This visual execution trace shows how to write a SQL query to get the top N rows per group. The query uses ROW_NUMBER() with PARTITION BY to assign a row number to each row within its group, ordered by a criteria such as salary descending. Then it filters to keep only rows where the row number is less than or equal to N, effectively selecting the top N rows per group. The execution table walks through each row, showing the assigned row number and whether it is included in the output. The variable tracker shows how the row number resets for each group. Key moments clarify why some rows are excluded and how partitioning works. The quiz tests understanding of row numbers and filtering. The snapshot summarizes the syntax and behavior for quick reference.