In this blog, we will break down how to retrieve the top 5 highest-paid employees from each department using SQL. This is a common query when working with databases that store information about employees and departments, and it involves ranking employees by their salary and returning the top earners for each department.
Problem Statement:
We want to retrieve the top 5 highest-paid employees in each department, sorted by salary in descending order. This means for each department, we need to rank employees by their salary, then limit the results to the top 5 for that department.
Example Schema:
Assume we have the following two tables:
Employee:EmployeeID(Primary Key)FirstNameLastNameSalaryDepartmentID(Foreign Key)
Department:DepartmentID(Primary Key)DepartmentName
SQL Query:
To solve this, we can use Common Table Expressions (CTEs) or Window Functions to rank employees by their salary within each department. The ROW_NUMBER() window function is particularly useful for this case, as it can assign a unique rank to each employee within a department, based on their salary.
Here’s how we can approach it:
WITH RankedEmployees AS ( SELECT e.EmployeeID, e.FirstName, e.LastName, e.Salary, d.DepartmentName, ROW_NUMBER() OVER (PARTITION BY e.DepartmentID ORDER BY e.Salary DESC) AS rank FROM Employee e JOIN Department d ON e.DepartmentID = d.DepartmentID ) SELECT EmployeeID, FirstName, LastName, Salary, DepartmentName FROM RankedEmployees WHERE rank <= 5 ORDER BY DepartmentName, Salary DESC;
Detailed Breakdown:
Common Table Expression (CTE):
- The
WITHclause is used to define a temporary result set namedRankedEmployees. This CTE allows us to simplify the query and avoid duplicating logic in theSELECTstatement.
- The
ROW_NUMBER() Function:
ROW_NUMBER()is a window function that assigns a unique row number to each row within a partition. Here, we partition the results byDepartmentIDusing thePARTITION BYclause. This means the row numbers will reset for each department.- The
ORDER BY e.Salary DESCensures that the highest salary gets the row number1, the second highest salary gets2, and so on.
Partitioning by Department:
- The
PARTITION BY e.DepartmentIDgroups the rows by department, so that the row numbers are applied separately for each department. This ensures that each department’s employees are ranked based on their salary, independent of other departments.
- The
Filtering Top 5 Employees:
- In the final
SELECTquery, we filter the results to only include employees whererank <= 5. This limits the result to the top 5 employees in each department.
- In the final
Sorting the Results:
- The results are sorted by
DepartmentNameand then bySalaryin descending order, which makes it easier to see the top-paid employees in each department in a structured format.
- The results are sorted by
Example Output:
Let's say we have the following data in the Employee and Department tables:
Key Takeaways:
- Window Functions like
ROW_NUMBER()are powerful for ranking and partitioning data without needing subqueries or multipleJOINoperations. - The use of
PARTITION BYallows you to rank data within specific groups (in this case, departments) while applying ranking logic across all rows. - This type of query is often used in real-world scenarios where businesses need to retrieve the top performers, highest-paid employees, or best-selling products by category.
Feel free to try this query in your own environment and see how the ROW_NUMBER() function can simplify complex ranking tasks in SQL.


Comments
Post a Comment