Salary Distribution Per Department (PERCENT_RANK & CUME_DIST)
For each employee show their PERCENT_RANK and CUME_DIST within their department (ascending salary), both rounded to 4 decimals. Return department_name, first_name, last_name, salary, percent_rank, cume_dist — ordered by department_name, salary, employee_id.
- Window functions
- Joins
- Sorting
Interview brief
Understand the request
For each employee show their PERCENT_RANK and CUME_DIST within their department (ascending salary), both rounded to 4 decimals. Return department_name, first_name, last_name, salary, percent_rank, cume_dist — ordered by department_name, salary, employee_id.
Data you will use
Review the relevant tables before deciding how to join, filter, or aggregate them.
employees
employee_idINTEGERfirst_nameVARCHAR(50)last_nameVARCHAR(50)salaryINTEGERdepartment_idINTEGER
departments
department_idINTEGERdepartment_nameVARCHAR(50)
Hints, when you need them
Open one clue at a time so you still do the reasoning.
Hint 1
PERCENT_RANK is 0 for the lowest row and 1 for the highest; lone rows in a partition get 0.
Hint 2
CUME_DIST is the fraction of rows at or below the current value — always > 0.
Hint 3
Both are ratio windows — no PARTITION argument, just OVER (PARTITION BY … ORDER BY …).
Verified SQL answer
Attempt the problem first, then compare structure and reasoning—not just syntax.
Reveal solution and explanation
SELECT d.department_name, e.first_name, e.last_name, e.salary, ROUND(PERCENT_RANK() OVER (PARTITION BY e.department_id ORDER BY e.salary), 4) AS percent_rank, ROUND(CUME_DIST() OVER (PARTITION BY e.department_id ORDER BY e.salary), 4) AS cume_dist FROM employees e INNER JOIN departments d ON e.department_id = d.department_id ORDER BY d.department_name, e.salary, e.employee_id;Why this works
PERCENT_RANK and CUME_DIST are the distribution windows. PERCENT_RANK answers 'what fraction ranked below me'; CUME_DIST answers 'what fraction are at or below my value'. They power compensation-band and percentile reporting.
Expected result
Use this output to verify values, aliases, ordering, and row count.
| department_name | first_name | last_name | salary | percent_rank | cume_dist |
|---|---|---|---|---|---|
| Engineering | Amanda | White | 75000 | 0 | 0.1667 |
| Engineering | Lisa | Anderson | 90000 | 0.2 | 0.3333 |
| Engineering | Robert | Williams | 95000 | 0.4 | 0.5 |
| Engineering | Emily | Chen | 125000 | 0.6 | 0.6667 |
| Engineering | David | Martinez | 130000 | 0.8 | 0.8333 |
| Engineering | Michael | Scott | 180000 | 1 | 1 |
| Executive | Jennifer | King | 250000 | 0 | 1 |
| Finance | Daniel | Lee | 70000 | 0 | 0.5 |
| Finance | Jessica | Moore | 105000 | 1 | 1 |
| Human Resources | Christopher | Wilson | 65000 | 0 | 0.5 |
Previewing 10 of 15 expected rows. Run the query in the editor to inspect the full result.
Learn the concepts behind this answer
Strengthen your understanding with these targeted learning topics: