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

这道题是之前那道Department Highest Salary的拓展,难度标记为Hard,还是蛮有难度的一道题,综合了前面很多题的知识点,首先看使用Select Count(Distinct)的方法,我们内交Employee和Department两张表,然后我们找出比当前薪水高的最多只能有两个,那么前三高的都能被取出来了,参见代码如下:

解法一:

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),是一样的效果:

解法二:

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 ..) 关键字来做:

解法三:

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的项即可,参见代码如下:

解法四:

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 题目讲解汇总(持续更新中...)

[LeetCode] Department Top Three Salaries 系里前三高薪水的更多相关文章

  1. LeetCode——Department Top Three Salaries(巧妙使用子查询)

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

  2. [SQL]LeetCode185. 部门工资前三高的员工 | Department Top Three Salaries

    SQL 架构 Create table If Not Exists Employee (Id ), Salary int, DepartmentId int) Create table If Not ...

  3. 【leetcode】Department Top Three Salaries

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

  4. LeetCode - 185. Department Top Three Salaries

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

  5. [LeetCode]-DataBase-Department Top Three Salaries

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

  6. 【SQL】185. Department Top Three Salaries

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

  7. [LeetCode] 347. Top K Frequent Elements 前K个高频元素

    Given a non-empty array of integers, return the k most frequent elements. Example 1: Input: nums = [ ...

  8. leetcode185 Department Top Three Salaries

    Employee表存储员工姓名.员工所在公寓.员工工资 Department表存储公寓id 评选出各个公寓的工资前三名的员工. 遇到的问题如下: limit,in等语句不能用在嵌套select语句中, ...

  9. 185. Department Top Three Salaries

    问题描述 解决方案 select b.name Department,a.name Employee,a.salary Salary from Employee a,Department b wher ...

随机推荐

  1. 使用 Windows Phone Toolkit 的 Tilt 效果

    上一篇文章分享了如何使控件具有摁下的效果(在WindowsPhone中使控件具有Tilt效果),实现方式是在项目中添加新的类文件,其实,如果项目引用了Windows Phone Toolkit,那么就 ...

  2. PowerShell 操作 Azure SQL Active Geo-Replication 实战

    <Azure SQL Database Active Geo-Replication简介>一文中,我们比较全面的介绍了 Azure SQL Database Active Geo-Repl ...

  3. IDEA上安装和使用checkstyle,findbugs,visualVM,PMD插件

    ##安装插件步骤: 1.打开settings 2.选择plugins 3.点击"Browse repositories" 4.搜索对应内插件,点击"install&quo ...

  4. SQL Server 随机数,随机区间,随机抽取数据rand(),floor(),ceiling(),round(),newid()函数等

    在查询分析器中执行:select rand(),可以看到结果会是类似于这样的随机小数:0.36361513486289558,像这样的小数在实际应用中用得不多,一般要取随机数都会取随机整数.那就看下面 ...

  5. MySQL的简单使用和JDBC示例

    MySql是关系型数据库管理系统(RDBMS),所谓的"关系型"可以把它当作是"表格"概念,事实上,一个关系型数据库由一个或数个表格组成. MySQL所使用的S ...

  6. WebService 概念和工作原理(一)

    今天我们一起来学习WebService.它到底是干啥用的? Web service是一个平台独立的,低耦合的,自包含的.基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集) ...

  7. 16款最佳的 jQuery Time Picker 时间选择插件

    jQuery 插件可以为你做许多事情,你可以很容易地把这些插件集成到您的网站.网络上的 jQuery 日期选择器和日历插件很多,但找不到很满意的时间选择器插件. 在这里,我们收集了最好的一组 jQue ...

  8. ArcGIS Engine开发前基础知识(4)

    ArcGIS不同开发方式的比较 关于GIS应用软件的开发,通常有三种方式:C/S架构.网络GIS和移动GIS.ArcGIS平台提供了对三种开发方式的支持,对于采用从C/S架构的大多数开发者来讲,首先想 ...

  9. Cocos2dx中线程优先级

    Cocos2dx中线程优先级问题 不论是ios还是android,遇到耗时的任务都要另起线程处理,否则程序不能及时用户的反馈.游戏中如果一圈循环不能在1/frameRate(帧率是30则1/30)秒内 ...

  10. 了解JavaScript 对象的属性操作

    提起操作, 很多人都会想到我们学习过程中最经常做的操作, 就是对数据库进行增, 删, 改, 查, 既然提到这个, 那么对于对象的属性操作也不例外, 基本上可以说也是这几个操作. JS中对象的属性标签 ...