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

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

因此,我的解题思路是这样的:

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

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

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

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的记录就是薪水的前三名。

    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。

    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 ;

【leetcode】Department Top Three Salaries的更多相关文章

  1. 【LeetCode】692. Top K Frequent Words 解题报告(Python)

    [LeetCode]692. Top K Frequent Words 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/problems/top ...

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

  3. 【leetcode】347. Top K Frequent Elements

    题目地址:https://leetcode.com/problems/top-k-frequent-elements/ 从一个数组中求解出现次数最多的k个元素,本质是top k问题,用堆排序解决. 关 ...

  4. 【LeetCode】347. Top K Frequent Elements 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 解题方法 字典 优先级队列 日期 题目地址:https://l ...

  5. 【LeetCode】代码模板,刷题必会

    目录 二分查找 排序的写法 BFS的写法 DFS的写法 回溯法 树 递归 迭代 前序遍历 中序遍历 后序遍历 构建完全二叉树 并查集 前缀树 图遍历 Dijkstra算法 Floyd-Warshall ...

  6. 【LeetCode】Island Perimeter 解题报告

    [LeetCode]Island Perimeter 解题报告 [LeetCode] https://leetcode.com/problems/island-perimeter/ Total Acc ...

  7. 【LeetCode】120. Triangle 解题报告(Python)

    [LeetCode]120. Triangle 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址htt ...

  8. 【LeetCode】36. Valid Sudoku 解题报告(Python)

    [LeetCode]36. Valid Sudoku 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址 ...

  9. 【LeetCode】895. Maximum Frequency Stack 解题报告(Python)

    [LeetCode]895. Maximum Frequency Stack 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxueming ...

随机推荐

  1. 将对象以json格式写入到文件中

    将 list 对象以json格式写入到文件中 try { ObjectMapper mapper = new ObjectMapper(); String value = mapper.writeVa ...

  2. MessageBox显示位置

    假设存在2个窗口类CImDlg与CChatDlg,如果希望MessageBox跟随CChatDlg,方法是 CChatDlg *pDlg = xxx; pDlg->MessageBox();

  3. 【转帖】网卡多队列技术与RSS功能介绍

    网卡多队列技术与RSS功能介绍 2017年02月08日 15:44:37 Murphy_0806 阅读数 10665 标签: rss网卡dpdk 更多 个人分类: DPDK https://blog. ...

  4. PreparedStatement 以及事务的注意事项

    a).PreparedStatement 可以进行批量操作,但是与Statement有一定的区别 1. Statement可以进行不同sql语句的批量操作 即可以同时进行 crud 操作. Strin ...

  5. 最长相同01数的子串(map搞搞)--牛客第三场 -- Crazy Binary String

    题意: 如题. 或者用我的数组分治也可以,就是有点愚蠢. //#include <bits/stdc++.h> #include <map> #include <iost ...

  6. 从入门到自闭之Python随机模块

    导入:import random 随机小数:random.random():大于0小于1之间的小数 指定数字之间的小数,不包含指定的最大值:random.uniform() 随机整数:random.r ...

  7. 基于VS搭建OpenCV环境

    OpenCV OpenCV的全称是Open Source Computer Vision Library,是一个跨平台的计算机视觉库.OpenCV是由英特尔公司发起并参与开发,以BSD许可证授权发行, ...

  8. 如何决定使用 HashMap 还是 TreeMap? (转)

    问:如何决定使用 HashMap 还是 TreeMap? 介绍 TreeMap<K,V>的Key值是要求实现java.lang.Comparable,所以迭代的时候TreeMap默认是按照 ...

  9. linux 下如何将网页版应用生成桌面图标

    使用linux mint已经两年了,很多国民应用,都没有Linux版,但是这些应用都有网页版,今天就说下最简单的将网页应用变成桌面应用,无需配置,安装任何插件.以微信为例; 首先,在谷歌浏览器打开网页 ...

  10. 剑指offer-孩子们的游戏(圆圈中最后剩下的数)-知识迁移能力-python

    题目描述 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此.HF作为牛客的资深元老,自然也准备了一些小游戏.其中,有个游戏是这样的:首先,让小朋友们围成一个大圈.然后,他随机指 ...