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. ASP.NET Core 中文文档 第三章 原理(7)配置

    原文:Configuration 作者:Steve Smith.Daniel Roth 翻译:刘怡(AlexLEWIS) 校对:孟帅洋(书缘) ASP.NET Core 支持多种配置选项.应用程序配置 ...

  2. [JSP]JSP 简介

    1.1 概述 1.1.1 什么是 JSP? JSP 全称是 Java Server Pages,是一种动态网页开发技术. 它与 PHP.ASP.ASP.NET 等语言类似,运行在服务端的语言. JSP ...

  3. 【QuickHit项目实例】

    关于java面向对象QuickHit项目实例 Game类:用来得到随机出现的字符串(随机打印的字符串,然后玩家进行输入字符串) public class Game { private String s ...

  4. 用C#实现MD5的加密(转载)

    方法一 首先,先简单介绍一下MD5 MD5的全称是message-digest algorithm 5(信息-摘要算法,在90年代初由mit laboratory for computer scien ...

  5. Nginx最大客户连接数算法一些遐想

    Nginx最大客户连接数算法一些遐想 现在很多互联网公司都在使用nginx,并且替换掉以前的Apache,nginx的优点就不说了,浅聊两句nginx的某些配置参数,找到这些参数设置的目的和关联性,并 ...

  6. C#——this关键字(1)

    //我的C#是跟着猛哥(刘铁猛)(算是我的正式老师)<C#语言入门详解>学习的,微信上猛哥也给我讲解了一些不懂得地方,对于我来说简直是一笔巨额财富,难得良师! 在学习C#的时候,老师讲的示 ...

  7. Oracle用户被锁原因及办法

    Oracle用户被锁原因及办法   在登陆时被告知test用户被锁 1.用dba角色的用户登陆,进行解锁,先设置具体时间格式,以便查看具体时间 SQL> alter session set nl ...

  8. Docker的ubuntu镜像安装的容器无ifconfig和ping命令的解决

    Docker的Ubuntu镜像安装的容器无ifconfig命令和ping命令 解决: apt-get update apt install net-tools       # ifconfig apt ...

  9. linux(十三)__vsftpd服务器

    rpm -qa |grep vsftpd yum search vsftpd yum install vsftpd 查看是否已经启动: service vsftpd status 启动: servic ...

  10. 5.1 JS中Object类型

    1.Object类型是引用类型中的一种. 2.创建Object实例(对象)的方式: 方式1:使用new操作符,后面跟上Object构造函数.如: var obj = new Object();//创建 ...