【leetcode】Department Top Three Salaries

The Employee table holds all employees. Every employee has an Id, and there is also a column for the department Id.spa

+----+-------+--------+--------------+
| Id | Name  | Salary | DepartmentId |
+----+-------+--------+--------------+
| 1  | Joe   | 70000  | 1            |
| 2  | Henry | 80000  | 2            |
| 3  | Sam   | 60000  | 2            |
| 4  | Max   | 90000  | 1            |
| 5  | Janet | 69000  | 1            |
| 6  | Randy | 85000  | 1            |
+----+-------+--------+--------------+

The Department table holds all departments of the company.code

+----+----------+
| Id | Name     |
+----+----------+
| 1  | IT       |
| 2  | Sales    |
+----+----------+

Write a SQL query to find employees who earn the top three salaries in each of the department. For the above tables, your SQL query should return the following rows.blog

+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT         | Max      | 90000  |
| IT         | Randy    | 85000  |
| IT         | Joe      | 70000  |
| Sales      | Henry    | 80000  |
| Sales      | Sam      | 60000  |
+------------+----------+--------+


这个题目属于hard级别,难点在于先组内排序,而后取组内前三的数据出来(排名可并列),最后再作一个组间排序。排序

所以,个人解题思路是这样的:three

1.把数据按照DepartmentId,Salary 排序,这样的话同一部门的数据在搜索的结果集中就在一块儿。ci

select DepartmentId, Name  ,Salary from Employee  order by DepartmentId ,Salary  desc

2.对同一部门的数据的记录进行编号,从1开始,若是和上一行的薪水相同,则编号和上一行同样。it

select DepartmentId, Salary,Name,  
      @num := if(@cid = DepartmentId ,if(@cursalry != Salary, @num + 1,@num), 1) as number,  
      @maxprice := if(@num = 1 ,@maxprice := Salary,@maxprice) as mp,  
      @cid := DepartmentId as dummy,  
      @cursalry:= Salary as curs  
    from  (select DepartmentId, Name  ,Salary from Employee  order by DepartmentId ,Salary  desc) e ,(select @num := 0,@maxprice := 0,@cid := 0,@cursalry = 0) b   
) c  

3.过滤掉编号大于 3的记录。由于数据已经排序过,因此编号小于等于3的记录就是薪水的前三名。table

    select c.DepartmentId, c.Name ,c.Salary from  
    (  
    select DepartmentId, Salary,Name,  
          @num := if(@cid = DepartmentId ,if(@cursalry != Salary, @num + 1,@num), 1) as number,  
          @maxprice := if(@num = 1 ,@maxprice := Salary,@maxprice) as mp,  
          @cid := DepartmentId as dummy,  
          @cursalry:= Salary as curs  
        from  (select DepartmentId, Name  ,Salary from Employee  order by DepartmentId ,Salary  desc) e ,(select @num := 0,@maxprice := 0,@cid := 0,@cursalry = 0) b   
    ) c where c.number <=3  
    ) g  

4.关联Department表,获取Department Name。class

    select f.Name as Department ,g.Name as Employee  ,g.Salary from  
    (  
    select c.DepartmentId, c.Name ,c.Salary from  
    (  
    select DepartmentId, Salary,Name,  
          @num := if(@cid = DepartmentId ,if(@cursalry != Salary, @num + 1,@num), 1) as number,  
          @maxprice := if(@num = 1 ,@maxprice := Salary,@maxprice) as mp,  
          @cid := DepartmentId as dummy,  
          @cursalry:= Salary as curs  
        from  (select DepartmentId, Name  ,Salary from Employee  order by DepartmentId ,Salary  desc) e ,(select @num := 0,@maxprice := 0,@cid := 0,@cursalry = 0) b   
    ) c where c.number <=3  
    ) g ,Department  f where  g.DepartmentId = f.Id ;  
相关文章
相关标签/搜索