LeetCode 185. Department Top Thr

2017-12-18  本文已影响0人  卡尔是正太

LeetCode 262. Trips and Users

题目

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

+----+-------+--------+--------------+
| 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.

+----+----------+
| 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.

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

题目大意

编写一个SQL查询来查找在每个部门中获得前三名工资的员工。对于上面的表,你的SQL查询应该返回下列行。

解题思路

这道题有点像 LeetCode 184. Department Highest Salary 的升级版
只不过这一次要找出每个部门最高的三个薪水

首先还是要用内联两表 满足 Departemnt字段的数据需求

... FROM Employee INNER JOIN Department ON Employee.DepartmentId  = Department.Id 

然后,既然要找出工资排名前三的人,就要满足两个查询条件 一是部门id相同 表示在同一个部门,二是比当前高的工资个数要小于 3 个。 按照这个思路,再使用相关子查询筛选结果

SELECT d.name AS Department, e.Name AS Employee, e.Salary 
FROM Employee AS e INNER JOIN Department AS d ON e.DepartmentId  = d.Id 
WHERE (SELECT count(Salary) FROM Employee WHERE DepartmentId = d.Id AND Salary > e.Salary ) < 3
ORDER BY e.Salary  DESC;

尝试提交结果报错,发现对于



这张表而言,本应输出
实际确输出了

这个测试实例里有两个相同的薪水,而且是符合前三条件的。 很明显,LeetCode 这里要求吧所有工资的人视为一个人,那么在salary 前加上 DISTINCT 即可

SELECT d.name AS Department, e.Name AS Employee, e.Salary 
FROM Employee AS e INNER JOIN Department AS d ON e.DepartmentId  = d.Id 
WHERE (SELECT count(DISTINCT Salary) FROM Employee WHERE DepartmentId = d.Id AND Salary > e.Salary ) < 3
ORDER BY e.Salary  DESC;

下面整理了几种其他的解法

[LeetCode] Department Top Three Salaries 系里前三高薪水

最后看了一下目前最快的解法

# Write your MySQL query statement below
SET @salary_rank=0;
SET @current_id=NULL;
SET @previous_salary=-1;

SELECT Department, Employee, Salary
FROM (SELECT Department, Employee, Salary,
    /*RANK() OVER (PARTITION BY E.Department ORDER BY E.Salary DESC) SalaryRank*/
    @salary_rank := IF(@current_id = Department, 
                       IF(@previous_salary = Salary, @salary_rank, @salary_rank + 1), 
                       1
                    ) AS SalaryRank,
    @current_id := Department,
    @previous_salary := Salary
    FROM (SELECT D.Name Department, E.Name Employee, E.Salary Salary
          FROM Employee E
          INNER JOIN Department D
            ON D.Id = E.DepartmentId
          Group By D.Name, E.Salary, E.Name
          Order By D.Name ASC, E.Salary DESC) E
    ) R
WHERE SalaryRank <= 3
/*ORDER BY Department ASC*/

这里使用用户自定义变量来对每一行生成了一个薪水排名(salaryrank)避免反复查表,优化了速度。

上一篇下一篇

猜你喜欢

热点阅读