Lesson Description
Number rows within a partition.
Lesson 1 of 4
Progress: 0/3 exercises solved (0%)
Solve all exercises below to unlock the next lesson.
Lesson Description
Number rows within a partition.
Easy Project
Mini project: Build a compensation ranking dashboard query with department-level rank and delta from the top earner.
Window functions compute a value for each row based on a set of related rows (a "window") without collapsing the result. The OVER() clause defines the window.
function() OVER (
PARTITION BY col -- divide rows into groups
ORDER BY col -- sort within each group
)
Assigns 1, 2, 3, … with no ties. Ties get different numbers (arbitrary order):
SELECT
first_name, department_id, salary,
ROW_NUMBER() OVER (
PARTITION BY department_id
ORDER BY salary DESC
) AS dept_rank
FROM employees;
Employees tied at salary share a rank; the next rank jumps:
salary RANK
12000 1
12000 1
9000 3 ← skipped 2
salary DENSE_RANK
12000 1
12000 1
9000 2 ← no gap
| Function | Ties | Gaps after ties |
|---|---|---|
| ROW_NUMBER | Unique numbers | — |
| RANK | Same number | Yes |
| DENSE_RANK | Same number | No |
Window functions cannot appear in WHERE. Wrap in a CTE or subquery:
WITH ranked AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rn
FROM employees
)
SELECT * FROM ranked WHERE rn = 1;
PARTITION BY is optional. Omitting it treats the whole result set as one partition.OVER() — each is independent.This lesson is part of Window Functions. Focus on the core idea in ROW_NUMBER and RANK, then validate with deliberate practice.
What to master
Common mistakes
High-level strategy
Task ladder
Transparent data checks
Retention loop
Logical reasoning for commands
WHERE
Why: Limits rows to only the business-relevant subset.
Memory cue: Filter early to reduce noise.
ORDER BY
Why: Makes output deterministic and reviewable.
Memory cue: No ORDER BY means no guaranteed row order.
AS alias
Why: Makes output columns readable for teams and reports.
Memory cue: If the name is clear, the query is easier to trust.
Concept check
3 quick questions. One at a time. Instant score at the end.
Return first_name, last_name, department_id, salary, and a column dept_rank that ranks employees within each department by salary descending (use ROW_NUMBER).
Return first_name, last_name, department_id, salary, and salary_rank using RANK() (not ROW_NUMBER) within each department ordered by salary descending.
Using a CTE with ROW_NUMBER(), return only the highest-paid employee per department. Show first_name, last_name, department_id, and salary, ordered by department_id.
Lesson 1 of 4
0/3 solved (0%)
Finish this lesson to unlock next.