Bird
Raised Fist0
SQLquery~10 mins

Top-N per group query in SQL - Interactive Code Practice

Choose your learning style10 modes available
Practice - 5 Tasks
Answer the questions below
1fill in blank
easy

Complete the code to select the top 1 salary per department.

SQL
SELECT department, employee, salary FROM employees WHERE salary = (SELECT MAX(salary) FROM employees WHERE department = [1]);
Drag options to blanks, or click blank then click option'
Adepartment
Bemployee
Csalary
Dposition
Attempts:
3 left
💡 Hint
Common Mistakes
Using employee instead of department in the subquery condition.
Using salary instead of department in the subquery condition.
2fill in blank
medium

Complete the code to assign row numbers partitioned by department ordered by salary descending.

SQL
SELECT department, employee, salary, ROW_NUMBER() OVER (PARTITION BY [1] ORDER BY salary DESC) AS rn FROM employees;
Drag options to blanks, or click blank then click option'
Adepartment
Bposition
Csalary
Demployee
Attempts:
3 left
💡 Hint
Common Mistakes
Partitioning by employee instead of department.
Partitioning by salary which does not group employees.
3fill in blank
hard

Fix the error in the query to select top 3 salaries per department using ROW_NUMBER.

SQL
SELECT department, employee, salary FROM (SELECT department, employee, salary, ROW_NUMBER() OVER (PARTITION BY department ORDER BY [1] DESC) AS rn FROM employees) sub WHERE rn <= 3;
Drag options to blanks, or click blank then click option'
Aemployee
Bdepartment
Csalary
Dposition
Attempts:
3 left
💡 Hint
Common Mistakes
Ordering by employee instead of salary.
Ordering by department which does not rank salaries.
4fill in blank
hard

Fill both blanks to select the top 2 employees by salary per department using DENSE_RANK.

SQL
SELECT department, employee, salary FROM (SELECT department, employee, salary, DENSE_RANK() OVER (PARTITION BY [1] ORDER BY [2] DESC) AS rank FROM employees) sub WHERE rank <= 2;
Drag options to blanks, or click blank then click option'
Adepartment
Bemployee
Csalary
Dposition
Attempts:
3 left
💡 Hint
Common Mistakes
Swapping partition and order columns.
Using employee instead of department for partition.
5fill in blank
hard

Fill all three blanks to select the top 1 salary per department using a correlated subquery.

SQL
SELECT department, employee, salary FROM employees e1 WHERE salary = (SELECT MAX([1]) FROM employees e2 WHERE e2.[2] = e1.[3]);
Drag options to blanks, or click blank then click option'
Asalary
Bdepartment
Cemployee
Dposition
Attempts:
3 left
💡 Hint
Common Mistakes
Using employee instead of salary in MAX.
Comparing employee columns instead of department.

Practice

(1/5)
1. What does the ROW_NUMBER() OVER (PARTITION BY column ORDER BY column) clause do in a SQL query?
easy
A. Assigns a unique rank number to each row within each group defined by the partition column.
B. Counts the total number of rows in the entire table.
C. Filters rows to only include those with the highest value in the column.
D. Joins two tables based on the partition column.

Solution

  1. Step 1: Understand ROW_NUMBER() function

    ROW_NUMBER() assigns a unique sequential number to rows in the result set.
  2. Step 2: Understand PARTITION BY usage

    PARTITION BY divides rows into groups, and ROW_NUMBER() restarts numbering for each group.
  3. Final Answer:

    Assigns a unique rank number to each row within each group defined by the partition column. -> Option A
  4. Quick Check:

    ROW_NUMBER() with PARTITION BY = unique rank per group [OK]
Hint: ROW_NUMBER() with PARTITION BY ranks rows per group [OK]
Common Mistakes:
  • Thinking ROW_NUMBER() counts total rows
  • Confusing PARTITION BY with filtering
  • Assuming it filters rows automatically
2. Which of the following SQL queries correctly selects the top 2 highest salaries per department from an employees table?
easy
A. SELECT * FROM (SELECT *, ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS rn FROM employees) sub WHERE rn <= 2;
B. SELECT * FROM employees ORDER BY salary DESC LIMIT 2 PARTITION BY department;
C. SELECT * FROM employees WHERE ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) <= 2;
D. SELECT TOP 2 * FROM employees PARTITION BY department ORDER BY salary DESC;

Solution

  1. Step 1: Understand ROW_NUMBER() usage in subquery

    ROW_NUMBER() must be used in a subquery or CTE to assign ranks before filtering.
  2. Step 2: Filter rows by rank in outer query

    The outer query filters rows where the rank (rn) is 2 or less per department.
  3. Final Answer:

    SELECT * FROM (SELECT *, ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS rn FROM employees) sub WHERE rn <= 2; -> Option A
  4. Quick Check:

    Use subquery with ROW_NUMBER() and filter by rank [OK]
Hint: Use subquery with ROW_NUMBER() then filter by rank [OK]
Common Mistakes:
  • Trying to filter ROW_NUMBER() directly in WHERE clause
  • Using LIMIT with PARTITION BY (not valid syntax)
  • Using TOP without proper partitioning
3. Given the table sales with columns region, salesperson, and amount, what will this query return?
SELECT region, salesperson, amount FROM (SELECT region, salesperson, amount, ROW_NUMBER() OVER (PARTITION BY region ORDER BY amount DESC) AS rn FROM sales) AS ranked WHERE rn = 1;
medium
A. All sales records sorted by amount descending.
B. All sales records where amount equals 1.
C. The highest sale amount record for each region.
D. The lowest sale amount record for each region.

Solution

  1. Step 1: Analyze ROW_NUMBER() with PARTITION BY region

    Rows are grouped by region and ranked by amount descending, so rn=1 is highest amount per region.
  2. Step 2: Filter WHERE rn = 1

    This keeps only the top-ranked row per region, i.e., the highest sale amount record.
  3. Final Answer:

    The highest sale amount record for each region. -> Option C
  4. Quick Check:

    ROW_NUMBER() = 1 per group returns top record [OK]
Hint: Filter WHERE rn=1 to get top record per group [OK]
Common Mistakes:
  • Thinking it returns all rows sorted
  • Confusing rn=1 with lowest amount
  • Assuming amount = 1 filters rows
4. Identify the error in this SQL query that tries to get the top 3 recent orders per customer from orders table:
SELECT customer_id, order_id, order_date, ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date DESC) AS rank FROM orders WHERE rank <= 3;
medium
A. Missing GROUP BY clause for customer_id.
B. ROW_NUMBER() cannot be used with PARTITION BY.
C. ORDER BY must be ascending, not descending.
D. You cannot filter on an alias in the WHERE clause directly.

Solution

  1. Step 1: Understand alias usage in WHERE clause

    Aliases like 'rank' defined in SELECT cannot be used in WHERE clause directly because WHERE is evaluated before SELECT.
  2. Step 2: Correct approach using subquery or CTE

    Use a subquery or CTE to assign ROW_NUMBER(), then filter on 'rank' in outer query.
  3. Final Answer:

    You cannot filter on an alias in the WHERE clause directly. -> Option D
  4. Quick Check:

    Filter on ROW_NUMBER() alias in outer query, not WHERE [OK]
Hint: Filter ROW_NUMBER() in outer query, not WHERE clause [OK]
Common Mistakes:
  • Using alias in WHERE clause directly
  • Thinking ORDER BY DESC is invalid
  • Adding unnecessary GROUP BY
5. You have a products table with columns category, product_id, and price. You want to find the top 2 most expensive products per category, but if two products have the same price, include both even if it means more than 2 per category. Which query achieves this?
hard
A. Use ROW_NUMBER() partitioned by category ordered by price DESC and filter WHERE rn <= 2.
B. Use RANK() partitioned by category ordered by price DESC and filter WHERE rank <= 2.
C. Use DENSE_RANK() partitioned by category ordered by price ASC and filter WHERE dense_rank <= 2.
D. Use COUNT() partitioned by category ordered by price DESC and filter WHERE count <= 2.

Solution

  1. Step 1: Understand difference between ROW_NUMBER(), RANK(), and DENSE_RANK()

    ROW_NUMBER() assigns unique ranks, so ties get different numbers. RANK() assigns same rank to ties and skips ranks after. DENSE_RANK() assigns same rank to ties but no gaps.
  2. Step 2: Choose RANK() to include ties at second place

    RANK() allows including all products tied at rank 2, possibly more than 2 rows per category.
  3. Final Answer:

    Use RANK() partitioned by category ordered by price DESC and filter WHERE rank <= 2. -> Option B
  4. Quick Check:

    RANK() includes ties with same rank [OK]
Hint: Use RANK() to include ties in top N per group [OK]
Common Mistakes:
  • Using ROW_NUMBER() excludes ties
  • Using DENSE_RANK() includes ties but no gaps
  • Using COUNT() is invalid for ranking
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard