|
| 1 | +# **185. Department Top Three Salaries** |
| 2 | + |
| 3 | +## **Problem Statement** |
| 4 | +You are given two tables: `Employee` and `Department`. |
| 5 | + |
| 6 | +### **Employee Table** |
| 7 | +```rb |
| 8 | ++--------------+---------+ |
| 9 | +| Column Name | Type | |
| 10 | ++--------------+---------+ |
| 11 | +| id | int | |
| 12 | +| name | varchar | |
| 13 | +| salary | int | |
| 14 | +| departmentId | int | |
| 15 | ++--------------+---------+ |
| 16 | +``` |
| 17 | +- `id` is the primary key. |
| 18 | +- `departmentId` is a foreign key referencing `id` in the `Department` table. |
| 19 | +- Each row represents an employee with their `id`, `name`, `salary`, and `departmentId`. |
| 20 | + |
| 21 | +### **Department Table** |
| 22 | +```rb |
| 23 | ++-------------+---------+ |
| 24 | +| Column Name | Type | |
| 25 | ++-------------+---------+ |
| 26 | +| id | int | |
| 27 | +| name | varchar | |
| 28 | ++-------------+---------+ |
| 29 | +``` |
| 30 | +- `id` is the primary key. |
| 31 | +- Each row represents a department with its `id` and `name`. |
| 32 | + |
| 33 | +### **Task:** |
| 34 | +Find employees who have a salary in the **top three unique salaries** in their respective departments. |
| 35 | + |
| 36 | +## **Example 1:** |
| 37 | +### **Input:** |
| 38 | +#### **Employee Table** |
| 39 | +``` |
| 40 | ++----+-------+--------+--------------+ |
| 41 | +| id | name | salary | departmentId | |
| 42 | ++----+-------+--------+--------------+ |
| 43 | +| 1 | Joe | 85000 | 1 | |
| 44 | +| 2 | Henry | 80000 | 2 | |
| 45 | +| 3 | Sam | 60000 | 2 | |
| 46 | +| 4 | Max | 90000 | 1 | |
| 47 | +| 5 | Janet | 69000 | 1 | |
| 48 | +| 6 | Randy | 85000 | 1 | |
| 49 | +| 7 | Will | 70000 | 1 | |
| 50 | ++----+-------+--------+--------------+ |
| 51 | +``` |
| 52 | +#### **Department Table** |
| 53 | +```rb |
| 54 | ++----+-------+ |
| 55 | +| id | name | |
| 56 | ++----+-------+ |
| 57 | +| 1 | IT | |
| 58 | +| 2 | Sales | |
| 59 | ++----+-------+ |
| 60 | +``` |
| 61 | +### **Output:** |
| 62 | +```rb |
| 63 | ++------------+----------+--------+ |
| 64 | +| Department | Employee | Salary | |
| 65 | ++------------+----------+--------+ |
| 66 | +| IT | Max | 90000 | |
| 67 | +| IT | Joe | 85000 | |
| 68 | +| IT | Randy | 85000 | |
| 69 | +| IT | Will | 70000 | |
| 70 | +| Sales | Henry | 80000 | |
| 71 | +| Sales | Sam | 60000 | |
| 72 | ++------------+----------+--------+ |
| 73 | +``` |
| 74 | + |
| 75 | +--- |
| 76 | + |
| 77 | +## **Solution Approaches** |
| 78 | + |
| 79 | +### **SQL Solution (Using Self Join)** |
| 80 | +```sql |
| 81 | +SELECT d.Name as Department, |
| 82 | + e.Name as Employee, |
| 83 | + e.Salary as Salary |
| 84 | +FROM Department d, Employee e |
| 85 | +WHERE ( |
| 86 | + SELECT COUNT(DISTINCT Salary) |
| 87 | + FROM Employee |
| 88 | + WHERE Salary > e.Salary AND DepartmentId = d.Id |
| 89 | +) < 3 AND e.DepartmentId = d.Id |
| 90 | +ORDER BY d.Id, e.Salary DESC; |
| 91 | +``` |
| 92 | +**Explanation:** |
| 93 | +- For each employee, we count how many distinct salaries are greater than theirs. |
| 94 | +- If fewer than 3 salaries are greater, the employee is in the **top three**. |
| 95 | +- We filter results by department and order by salary in descending order. |
| 96 | + |
| 97 | +--- |
| 98 | + |
| 99 | +### **SQL Solution (Using Window Functions)** |
| 100 | +```sql |
| 101 | +WITH RankedSalaries AS ( |
| 102 | + SELECT e.name AS Employee, |
| 103 | + e.salary AS Salary, |
| 104 | + d.name AS Department, |
| 105 | + DENSE_RANK() OVER (PARTITION BY e.departmentId ORDER BY e.salary DESC) AS rnk |
| 106 | + FROM Employee e |
| 107 | + JOIN Department d ON e.departmentId = d.id |
| 108 | +) |
| 109 | +SELECT Department, Employee, Salary |
| 110 | +FROM RankedSalaries |
| 111 | +WHERE rnk <= 3; |
| 112 | +``` |
| 113 | +**Explanation:** |
| 114 | +- We use `DENSE_RANK()` to assign a rank to salaries within each department. |
| 115 | +- `PARTITION BY departmentId` ensures ranking is specific to each department. |
| 116 | +- Employees with `rnk <= 3` are returned. |
| 117 | + |
| 118 | +--- |
| 119 | + |
| 120 | +### **Pandas Solution** |
| 121 | +```python |
| 122 | +import pandas as pd |
| 123 | + |
| 124 | +def department_top_three_salaries(employee: pd.DataFrame, department: pd.DataFrame) -> pd.DataFrame: |
| 125 | + # Merge employee and department tables |
| 126 | + employee = employee.merge(department, left_on='departmentId', right_on='id', suffixes=('', '_dept')) |
| 127 | + |
| 128 | + # Rank employees' salaries within each department |
| 129 | + employee['rank'] = employee.groupby('departmentId')['salary'].rank(method='dense', ascending=False) |
| 130 | + |
| 131 | + # Filter top 3 salaries in each department |
| 132 | + result = employee[employee['rank'] <= 3][['name_dept', 'name', 'salary']] |
| 133 | + |
| 134 | + # Rename columns to match the expected output |
| 135 | + result.columns = ['Department', 'Employee', 'Salary'] |
| 136 | + |
| 137 | + return result |
| 138 | +``` |
| 139 | +**Explanation:** |
| 140 | +- Merge the `Employee` and `Department` tables. |
| 141 | +- Rank salaries within each department using `.rank()`. |
| 142 | +- Filter the top 3 ranked salaries per department. |
| 143 | + |
| 144 | +--- |
| 145 | + |
| 146 | +## **File Structure** |
| 147 | +``` |
| 148 | +📂 LeetCode185 |
| 149 | +│── 📜 problem_statement.md |
| 150 | +│── 📜 sql_self_join_solution.sql |
| 151 | +│── 📜 sql_window_function_solution.sql |
| 152 | +│── 📜 pandas_solution.py |
| 153 | +│── 📜 README.md |
| 154 | +``` |
| 155 | +- `problem_statement.md` → Contains the problem description and constraints. |
| 156 | +- `sql_self_join_solution.sql` → Contains the SQL solution using self-join. |
| 157 | +- `sql_window_function_solution.sql` → Contains the SQL solution using `DENSE_RANK()`. |
| 158 | +- `pandas_solution.py` → Contains the Pandas solution for Python users. |
| 159 | +- `README.md` → Provides an overview of the problem and solutions. |
| 160 | + |
| 161 | +--- |
| 162 | + |
| 163 | +## **Useful Links** |
| 164 | +- [LeetCode Problem 185](https://leetcode.com/problems/department-top-three-salaries/) |
| 165 | +- [SQL DENSE_RANK() Function](https://www.w3schools.com/sql/sql_functions.asp) |
| 166 | +- [Pandas Rank Documentation](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.rank.html) |
| 167 | + |
| 168 | +--- |
| 169 | + |
0 commit comments