Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一、题目描述:
题目来源:LeetCode>部门工资最高的员工
表:Employee
| 列名 | 类型 |
|---|---|
| id | int |
| name | varchar |
| salary | int |
| departmentId | int |
id是此表的主键列。 departmentId是Department表中ID的外键。 此表的每一行都表示员工的ID、姓名和工资。它还包含他们所在部门的ID。
表:Department
| 列名 | 类型 |
|---|---|
| id | int |
| name | varchar |
| id是此表的主键列。 | |
| 此表的每一行都表示一个部门的ID及其名称。 |
编写SQL查询以查找每个部门中薪资最高的员工。 按 任意顺序 返回结果表。 查询结果格式如下例所示。
示例 1:
输入: Employee 表:
| id | name | salary | departmentId |
|---|---|---|---|
| 1 | Joe | 70000 | 1 |
| 2 | Jim | 90000 | 1 |
| 3 | Henry | 80000 | 2 |
| 4 | Sam | 60000 | 2 |
| 5 | Max | 90000 | 1 |
Department 表:
| id | name |
|---|---|
| 1 | IT |
| 2 | Sales |
输出:
| Department | Employee | Salary |
|---|---|---|
| IT | Jim | 90000 |
| Sales | Henry | 80000 |
| IT | Max | 90000 |
解释:Max 和 Jim 在 IT 部门的工资都是最高的,Henry 在销售部的工资最高。
二、思路分析:
- 首先回忆一下GROUP BY 语句的用法特点:根据字段进行分组
- 首对对Employee表进行统计,使用group by统计出工资最高的部门id和薪资
SELECT
DepartmentId,
max( Salary ) AS maxSalary
FROM
Employee
GROUP BY
DepartmentId;
- 再根据 DepartmentId 字段连接 Department 表,根据 Salary 和 DepartmentId 查找 Department表的Name 字段
三、AC 代码:
SELECT
Department.NAME AS Department,
Employee.NAME AS Employee,
Salary
FROM
Employee,
Department
WHERE
Employee.DepartmentId = Department.Id
AND ( Employee.DepartmentId, Salary ) IN ( SELECT DepartmentId, max( Salary ) AS maxSalary FROM Employee GROUP BY DepartmentId );
四、总结:
此题还可以用另一种解法,先找出部门相同,薪资最高的员工。
先将工资排序,筛选出部门相同且薪资更高的数据
SELECT
*
FROM
Employee e1,
Employee e2
WHERE
e1.DepartmentId = e2.DepartmentId
AND e2.Salary > e1.Salary
ORDER BY
Salary;
在外层使用not exists,排除子查询中的数据,并且与部门表进行内连接,即如果一条数据对应的部门为空,则不返回这条数据,此时临时表中的所有数据都符合条件,所以不带条件全部选出。
WITH result AS (
SELECT
d.NAME AS Department,
e1.NAME AS Employee,
e1.Salary
FROM
Employee e1
INNER JOIN Department d ON e1.DepartmentId = d.Id
WHERE
NOT EXISTS ( SELECT * FROM Employee e2 WHERE e1.DepartmentId = e2.DepartmentId AND e2.Salary > e1.Salary ORDER BY Salary )
) SELECT
*
FROM
result;