文章目录
🐴 1.SQL题目概述
LeetCode原题链接
表: Employee +--------------+---------+ | Column Name | Type | +--------------+---------+ | id | int | | name | varchar | | salary | int | | departmentId | int | +--------------+---------+ Id是该表的主键列。 departmentId是Department表中ID的外键。 该表的每一行都表示员工的ID、姓名和工资。它还包含了他们部门的ID。 表: Department +-------------+---------+ | Column Name | Type | +-------------+---------+ | id | int | | name | varchar | +-------------+---------+ Id是该表的主键列。 该表的每一行表示部门ID和部门名。
🚀题目:
公司的主管们感兴趣的是公司每个部门中谁赚的钱最多。
一个部门的 高收入者 是指一个员工的工资在该部门的 不同 工资中 排名前三 。
编写一个SQL查询,找出每个部门中 收入高的员工 。
以 任意顺序 返回结果表。
查询结果格式如下所示。
🚩查询结果如下例所示 输入: 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的工资最高 - 兰迪和乔都赚取第二高的独特的薪水 - 威尔的薪水是第三高的 在销售部: - 亨利的工资最高 - 山姆的薪水第二高 - 没有第三高的工资,因为只有两名员工
🐴 2.解题思路
MySQL8.0 中专门有开创窗口函数实现上述排名,但是一定使用正确的窗口函数排序
ROW_NUMBER(),DENSE_RANK(),RANK() 这三个区别哈,
这里使用DENSE_RANK(),即并列排名连续不间断
需要注意的一点是 as 后的别名,千万不要与前面的函数名重名,否则会报错
Oracle中直接有对应的开窗函数 DENSE_RANK()处理
邦德这里使用了数据库自带的开窗函数来解题,
如果小伙伴们还有其他解题思路,欢迎评论区留言交流~
🐴 3.方法实现
🌈Oracle实现
select m.Department as “Department”, m.Employee as “Employee”, m.Salary as “Salary” from ( SELECT b.name AS “DEPARTMENT”, a.name AS “EMPLOYEE”, a.Salary, DENSE_RANK() OVER(partition by a.departmentId ORDER BY a.salary desc) rank FROM Employee a,Department b where a.departmentId = b.id ) m where rank<=3;
🌈MySQL实现
select m.Department, m.Employee, m.Salary from ( SELECT b.name AS ‘Department’, a.name AS ‘Employee’, a.Salary, DENSE_RANK() OVER w AS ‘rank’ FROM Employee a,Department b where a.departmentId = b.id WINDOW w AS (partition by a.departmentId ORDER BY a.salary desc) ) m where m.rank<=3;
🐴 4.代码测试
🌈Oracle实现
执行代码,开始测试
与测试结果一致,测试成功!
🌈MySQL实现
执行代码,开始测试
与测试结果一致,测试成功!
🐴 5.知识点小结
MySQL8.0 中可以利用 ROW_NUMBER(),DENSE_RANK(),RANK() 三个窗口函数实现
1.普通排名: ROW_NUMBER()
按分数高低直接排名,从 1 开始,往下排,类似于 row number
分数相同,名次相同,排名无间隔:DENSE_RANK()
另外一种排名方式是相同的值排名相同,相同值的下一个名次应该是跳跃整数值,即排名有间隔
RANK()
综上所术,我们这里选择了DENSE_RANK()来解题