题目描述
(通过次数145,057 | 提交次数288,684,通过率50.25%)
表: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 在销售部的工资最高。 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/department-highest-salary
//测试数据 Create table If Not Exists Employee (id int, name varchar(255), salary int, departmentId int); Create table If Not Exists Department (id int, name varchar(255)); insert into Employee (id, name, salary, departmentId) values ('1', 'Joe', '70000', '1'); insert into Employee (id, name, salary, departmentId) values ('2', 'Jim', '90000', '1'); insert into Employee (id, name, salary, departmentId) values ('3', 'Henry', '80000', '2'); insert into Employee (id, name, salary, departmentId) values ('4', 'Sam', '60000', '2'); insert into Employee (id, name, salary, departmentId) values ('5', 'Max', '90000', '1'); insert into Department (id, name) values ('1', 'IT'); insert into Department (id, name) values ('2', 'Sales');
解题思路
这是一个关于开窗函数的入门题。
可以说,** 对开窗函数掌握的熟练程度,是衡量一个数据人水平的分水岭 **。
在实际工作中,开窗函数也会经常使用到,对它们的区别及使用场景的考察,在面试和笔试的过程中经常会碰到,也是必须要掌握的。
我在面试的过程中,就经常会问到相关的问题。如果面试者答不上来,基本就被pass掉了。
一般来说,常用的开窗(分析)函数有如下3个:
** row_number **:为每一行返回一个唯一的数字,排名相等则按随机顺序返回排名。或者同时指定另一个字段,作为辅助排名的手段,以便在排名相等时,能够决定不同行的顺序。如:1,2,3,4,5。。。
** rank **:排名相等的情况下返回相同的排名,但排名结果会有断档。如:1,1,3,4,4,4,7,8,9。。。
** dense_rank **:排名相等的情况下返回相同的排名,但排名结果不会有断档。如:1,1,1,2,3,3,4,5,6,7,7,7,7,8,9。。。
因为本题要求,薪水相同的员工都需要返回,并且,只返回薪水最高的员工。那么,使用rank和dense_rank,都是可以满足本题要求的。
可以通过如下步骤,计算出题目要求的结果:
** 第一步 **:按部门开窗,算出每个部门每个人的薪水排名。薪水最高的排在第1位。
** 第二步 **:过滤出薪水排名为1的员工。
** 第三步 **:关联出部门的名称并返回。
参考SQL
未特别说明的情况下,参考SQL为基于MySQL8.0实现。
select c.name Department, b.name Employee, b.salary from ( select a.name,a.salary,a.departmentId, rank() over(partition by a.departmentId order by a.salary desc) rk from Employee a )b left join Department c on b.departmentId = c.id where b.rk = 1 ;
本站所有内容均为原创,本站保留所有权利。仅允许非商业用途的转载,但必须注明来源网站、作者、来源链接!否则,由此造成的一切后果,由转载方承担!
干货分享、技术提升、面试笔试、学习交流,欢迎关注公众号:xuesql。QQ学习交流群:209942678。