题目描述
表: Employee
+--------------+---------+ | Column Name | Type | +--------------+---------+ | id | int | | name | varchar | | salary | int | | departmentId | int | +--------------+---------+ id 是该表的主键列(具有唯一值的列)。 departmentId 是 Department 表中 ID 的外键(reference 列)。 该表的每一行都表示员工的ID、姓名和工资。它还包含了他们部门的ID。
表: Department
+-------------+---------+ | Column Name | Type | +-------------+---------+ | id | int | | name | varchar | +-------------+---------+ id 是该表的主键列(具有唯一值的列)。 该表的每一行表示部门ID和部门名。
公司的主管们感兴趣的是公司每个部门中谁赚的钱最多。一个部门的 高收入者 是指一个员工的工资在该部门的 不同 工资中 排名前三 。
编写解决方案,找出每个部门中 收入高的员工 。
以 任意顺序 返回结果表。
返回结果格式如下所示。
示例 1:
输入: Employee 表: +----+-------+--------+--------------+ | id | name | salary | departmentId | +----+-------+--------+--------------+ | 1 | Joe | 85000 | 1 | | 2 | Henry | 80000 | 2 | | 3 | Sam | 60000 | 2 | | 4 | Max | 90000 | 1 | | 5 | Janet | 69000 | 1 | | 6 | Randy | 85000 | 1 | | 7 | Will | 70000 | 1 | +----+-------+--------+--------------+ Department 表: +----+-------+ | id | name | +----+-------+ | 1 | IT | | 2 | Sales | +----+-------+ 输出: +------------+----------+--------+ | Department | Employee | Salary | +------------+----------+--------+ | IT | Max | 90000 | | IT | Joe | 85000 | | IT | Randy | 85000 | | IT | Will | 70000 | | Sales | Henry | 80000 | | Sales | Sam | 60000 | +------------+----------+--------+ 解释: 在IT部门: - Max的工资最高 - 兰迪和乔都赚取第二高的独特的薪水 - 威尔的薪水是第三高的 在销售部: - 亨利的工资最高 - 山姆的薪水第二高 - 没有第三高的工资,因为只有两名员工
思路整理
-
排名分析: 我们需要为每个部门的员工根据工资进行排名。由于需要找出工资排名前三的员工,我们可以使用MySQL的窗口函数
DENSE_RANK()
来实现。DENSE_RANK()
会在工资相同时赋予相同的排名,并且排名不会因为相同而跳跃(例如,两个并列第一后,下一个直接是第二)。 -
部门关联: 为了获取员工的部门名称,我们需要将
Employee
表和Department
表进行连接(JOIN),通过departmentId
和id
字段关联。 -
数据筛选: 使用排名信息筛选出每个部门工资排名前三的员工。
-
结果格式: 最后,选择部门名称、员工姓名和工资,按部门和工资排序。
完整代码及解释
SELECT
AS Department,
AS Employee,
e.salary AS Salary
FROM
(SELECT
*,
DENSE_RANK() OVER (PARTITION BY departmentId ORDER BY salary DESC) AS salary_rank
FROM Employee) e
JOIN Department d ON e.departmentId = d.id
WHERE e.salary_rank <= 3
ORDER BY , e.salary DESC;
- 子查询部分:对
Employee
表使用窗口函数DENSE_RANK()
,在departmentId
分组内按照salary
降序排名,并将结果命名为salary_rank
。 JOIN
操作:将上述子查询的结果与Department
表进行连接,以获取部门名称。WHERE
子句:筛选出排名在前三的记录。ORDER BY
:最后的结果按部门名称和工资降序排序,以符合题目要求的输出格式。
这个查询假设每个部门的员工工资都可能不同。如果部门内有工资相同的员工,DENSE_RANK()
会给这些员工相同的排名,并且不会跳过任何排名(即如果有两个第一名,下一个排名直接是第二,而不是第三)。这正符合题目中对“高收入者”的定义。
通过