LeetCode力扣刷题数据库(184):部门工资最高的员工

该博客介绍了一种SQL查询方法,用于从Employee和Department表中找出每个部门薪资最高的员工。通过左连接、分组和子查询或连接查询,可以解决可能存在多个员工薪资相同且最高的情况。错误的查询示例和正确的解决方案都被详细阐述,强调了在SQL聚合查询中需要注意的细节。
摘要由CSDN通过智能技术生成

184:部门工资最高的员工

表: 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 在销售部的工资最高。

解题思路

首先Employee left join Department得到一个员工信息和部门信息关联的临时表。
然后group by DepartmentId分组,从每个组中找出max值。

错误示范1

select d.Name as Department, e.Name as Employee, max(Salary) as Salary
from Employee e left join Department d on e.DepartmentId = d.Id
group by e.DepartmentId;

上述代码错误的原因是,select中的max只挑选出了一个最大值,而忽略了可能有多个员工的薪资同为最大值的情况。
并且!select找出的max(Salary)并不是对应的行的Salary,而是整个组中的Salary。另外还存在的问题是,对于mysql 5.7及以上的版本,select的字段必须是被group by包含的字段,或是使用聚合函数。

错误示范2

select d.Name as Department, e.Name as Employee, Salary
from Employee e left join Department d on e.DepartmentId = d.Id
group by e.DepartmentId
having Salary = max(Salary);

上述代码看似解决了max只能去除最大值的问题,以及max(Salary)不是对应行的Salary的问题.
但是having子句中是不能出现非聚合函数中的属性名的,原因是group by分组之后得到的是组中的1条数据,所以having Salary只能获得这一条数据的Salary。
解决方法是不要在having子句中出现非聚合函数和非具体数据的其他字段。

解法一:子查询

首先找出每个分组及其最大值,然后判断表中每条数据的分组和Salary是否和这个相等。

select d.Name as Department, e.Name as Employee, Salary
from Employee e join Department d on e.DepartmentId = d.Id
where (e.DepartmentId, e.Salary) in (
    select DepartmentId, max(Salary)
    from Employee
    group by DepartmentId
);

解法二:连接查询

Employee和查询出来的每个分组的最大值连接。

select d.Name as Department, e.Name as Employee, e.Salary
from Employee e join Department d on e.DepartmentId = d.Id join (
    select DepartmentId, max(Salary) as Salary
    from Employee
    group by DepartmentId) t on e.DepartmentId = t.DepartmentId and e.Salary = t.Salary;


来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/department-highest-salary
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值