[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.html

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

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

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

 

這道題是以前那道Department Highest Salary的拓展,難度標記爲Hard,仍是蠻有難度的一道題,綜合了前面不少題的知識點,首先看使用Select Count(Distinct)的方法,咱們內交Employee和Department兩張表,而後咱們找出比當前薪水高的最多隻能有兩個,那麼前三高的都能被取出來了,參見代碼以下:spa

 

解法一:code

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

 

下面這種方法將上面方法中的<3換成了IN (0, 1, 2),是同樣的效果:htm

 

解法二:blog

SELECT d.Name AS Department, e.Name AS Employee, e.Salary FROM Employee e, Department d
WHERE (SELECT COUNT(DISTINCT Salary) FROM Employee WHERE Salary > e.Salary
AND DepartmentId = d.Id) IN (0, 1, 2) AND e.DepartmentId = d.Id ORDER BY d.Name, e.Salary DESC;

 

或者咱們也能夠使用Group by Having Count(Distinct ..) 關鍵字來作:three

 

解法三:leetcode

SELECT d.Name AS Department, e.Name AS Employee, e.Salary FROM 
(SELECT e1.Name, e1.Salary, e1.DepartmentId FROM Employee e1 JOIN Employee e2 
ON e1.DepartmentId = e2.DepartmentId AND e1.Salary <= e2.Salary GROUP BY e1.Id 
HAVING COUNT(DISTINCT e2.Salary) <= 3) e JOIN Department d ON e.DepartmentId = d.Id 
ORDER BY d.Name, e.Salary DESC;

 

下面這種方法略微複雜一些,用到了變量,跟Consecutive Numbers中的解法三使用的方法同樣,目的是爲了給每一個人都按照薪水的高低增長一個rank,最後返回rank值小於等於3的項便可,參見代碼以下:get

 

解法四:

SELECT d.Name AS Department, e.Name AS Employee, e.Salary FROM 
(SELECT Name, Salary, DepartmentId,
@rank := IF(@pre_d = DepartmentId, @rank + (@pre_s <> Salary), 1) AS rank,
@pre_d := DepartmentId, @pre_s := Salary 
FROM Employee, (SELECT @pre_d := -1, @pre_s := -1, @rank := 1) AS init
ORDER BY DepartmentId, Salary DESC) e JOIN Department d ON e.DepartmentId = d.Id
WHERE e.rank <= 3 ORDER BY d.Name, e.Salary DESC;

 

相似題目:

Department Highest Salary

Second Highest Salary

Combine Two Tables

 

參考資料:

https://leetcode.com/discuss/23002/my-tidy-solution

https://leetcode.com/discuss/91087/yet-another-solution-using-having-count-distinct

https://leetcode.com/discuss/69880/two-solutions-1-count-join-2-three-variables-join

 

LeetCode All in One 題目講解彙總(持續更新中...)

相關文章
相關標籤/搜索