预备知识
首先需要了解“各组得分最高的员工”要如何求解,参考这篇文章:
如何查找各组得分最高的员工?以“部门工资最高的员工”为例。
类比”184.部门工资最高的员工“,可以考虑找出每个分组的工资前三高的值,然后通过子查询或者是连接这个临时表找出各组工资前三高的员工。
但实际上,各组前三高的工资并不能像各组最高的工资一样直接group by就能求出,所以这个方法并没有想象中那么简单。
前N高的含义
所以可以考虑工资前N高的含义,即工资比这些员工高的不到N个。
以下以 leetcode 185.部门工资前三高的所有员工为例。
1. 子查询
可以使用子查询,对于每一条数据在子查询中查找工资更高的,并通过count()统计个数。
由于子查询跟外部查询相关,因此这里的子查询是相关子查询,对于外部的每一条数据都要进行一次子查询,效率较低。
1 | select d.Name as Department, e1.name as Employee, e1.Salary |
2. 自连接
由于上述相关子查询的效率较低,因此可以考虑使用自连接,通过on控制条件,使得连接起来的数据属于同一个部门,并且之前存在工资的大小关系。
这条连接查询语句的效率要比上述使用相关子查询的语句高。
1 | select d.Name as Department, e1.name as Employee, e1.Salary |
扩展
类似地,也可以使用这种方法找出”所有人中排名前N的员工“(可以直接order by),”每个组中排名前N的员工“,以及”所有人/每个部门排名第N的员工“(order by … limit 或上述换为等号)等。