Leetcode的SQL题解:185. 部门工资前三高的员工
题目
查询部门工资前三高的员工。
我用的数据库是oracle。
下面是数据表的信息。
Employee表数据:
| ID | NAME | Salary | DepartmentId |
| -- | ---- | ------ | ------------ |
|1 | Joe | 85000 | 1 |
|2 | Henry | 80000 | 2 |
|3 | Sam | 60000 | 2 |
|4 | Max | 90000 | 1 |
|5 | Janet | 69000 | 1 |
|6 | Randy | 85000 | 1 |
|7 | Will | 70000 | 1 |
|8 | edav | 50000 | 2 |
|9 | easonv | 40000 | 2 |
8、9行为我自行添加,为了更清晰展示查询结果。
创建表
Employee 表包含所有员工信息,每个员工有其对应的 Id, salary 和 department Id 。
create table Employee (
Id number(5),
Name varchar2(10) ,
Salary number(5),
DepartmentId number(5)
);
Department 表包含公司所有部门的信息。
create table Department (
Id number(5),
Name varchar2(10)
);
插入数据Employee,脚本如下
insert into Employee (ID, NAME, SALARY, DEPARTMENTID)
values ('1', 'Joe', '85000', '1');
insert into Employee (ID, NAME, SALARY, DEPARTMENTID)
values ('2', 'Henry', '80000', '2');
insert into Employee (ID, NAME, SALARY, DEPARTMENTID)
values ('3', 'Sam', '60000', null);
insert into Employee (ID, NAME, SALARY, DEPARTMENTID)
values ('4', 'Max', '90000', '1');
insert into Employee (ID, NAME, SALARY, DEPARTMENTID)
values ('5', 'Janet', '69000', '1');
insert into Employee (ID, NAME, SALARY, DEPARTMENTID)
values ('6', 'Randy', '85000', '1');
insert into Employee (ID, NAME, SALARY, DEPARTMENTID)
values ('7', 'Will', '70000', '1');
insert into Employee (ID, NAME, SALARY, DEPARTMENTID)
values ('8', 'eda', '50000', '2');
insert into Employee (ID, NAME, SALARY, DEPARTMENTID)
values ('9', 'eason', '40000', '2');
插入数据Department,脚本如下
insert into Department (ID, NAME)
values ('1', 'IT');
insert into Department (ID, NAME)
values ('2', 'Sales');
查询
以下使用四种SQL语句查出的结果,前两个是用oracle特有函数,后两个是标准SQL92写法。
你觉得哪个对?哪个性能高?
函数1 ROW_NUMBER
select Department,Employee,Salary
from (select (ROW_NUMBER()
over(PARTITION by t1.departmentid order by Salary desc)) lev,
t2.name Department,
t1.name Employee,
t1.Salary Salary
from Employee t1, Department t2
where t1.departmentid = t2.id) A
where lev <= 3;
函数2 dense_rank
select D.Name Department, E.Name Employee, E.Salary Salary
from (select Name,
Salary,
DepartmentId,
dense_rank() over(partition by DepartmentId order by Salary desc) Trank
from Employee) E
right join Department D
on E.DepartmentId = D.id
where Trank <= 3;
通用写法1
select d.name as Department, e.name as Employee, e.salary as Salary
from employee e
inner join department d
on e.DepartmentId = d.id
where (select count(distinct salary)
from employee
where salary > e.salary
and departmentid = e.DepartmentId) < 3
order by e.departmentid, Salary desc;
通用写法2
SELECT t3.name Department, t2.name Employee, t2.salary Salary
FROM Employee t2, Department t3
WHERE t2.id NOT IN (SELECT b.id
FROM Employee a, Employee b
WHERE a.DepartmentId = b.DepartmentId
AND a.salary > b.salary
GROUP BY b.id
HAVING COUNT(*) >= 3)
AND t2.DepartmentId = t3.id
ORDER BY Department, t2.salary DESC;
吐槽
感兴趣的同学可以自己跑下。
我个人觉得所谓官方答案是有问题的。
官方题解如下,mysql版本:
SELECT d.Name AS 'Department', e1.Name AS 'Employee', e1.Salary
FROM Employee e1
JOIN Department d
ON e1.DepartmentId = d.Id
WHERE 3 > (SELECT COUNT(DISTINCT e2.Salary)
FROM Employee e2
WHERE e2.Salary > e1.Salary
AND e1.DepartmentId = e2.DepartmentId);
改写成oracle版,加上排序:
SELECT d.Name Department, e1.Name Employee, e1.Salary
FROM Employee e1
JOIN Department d
ON e1.DepartmentId = d.Id
WHERE 3 > (SELECT COUNT(DISTINCT e2.Salary)
FROM Employee e2
WHERE e2.Salary > e1.Salary
AND e1.DepartmentId = e2.DepartmentId)
order by d.id,salary desc
查出来的数据是与通用写法1一样的,
两个同样的85000的数据
|序号| Department | Employee | Salary |
|--- | ---- | ------- | ------------ |
|1 | IT | Max | 90000
|2 | IT | Randy | 85000
|3 | IT | Joe | 85000
|4 | IT | Will | 70000
|5 | Sales | Henry | 80000
|6 | Sales | Sam | 60000
|7 | Sales | eda| 50000
这个题目出的歧义太大,如果是在考试中,应该是查出前三名、前四名的都对。
个人认为应该查出前三名应该是不包含70000这条数据的,就算是并列第二,那么就应该没有第三了,高校排名不也是这样吗?
所以私以为正确答案应该是查出这样的数据
|序号| Department | Employee | Salary |
|--- | ---- | ------- | ------------ |
|1 | IT | Max | 90000
|2 | IT | Randy | 85000
|3 | IT | Joe | 85000
|4 | Sales | Henry | 80000
|5 | Sales | Sam | 60000
|6 | Sales | eda| 50000
那么,我写的四条语句中,应该是函数1及通用写法2可以满足这个条件。
我的公众号

Leetcode的SQL题解:185. 部门工资前三高的员工的更多相关文章
- [SQL]LeetCode185. 部门工资前三高的员工 | Department Top Three Salaries
SQL 架构 Create table If Not Exists Employee (Id ), Salary int, DepartmentId int) Create table If Not ...
- sql查询:部门工资前三高的员工和部门工资最高的员工
创建表:Create table If Not Exists Employee (Id int, Name varchar(255), Salary int, DepartmentId int);Cr ...
- 185. 部门工资前三高的所有员工 + 多表联合 + join + dense_rank()
185. 部门工资前三高的所有员工 LeetCode_MySql_185 题目描述 方法一:使用join on # Write your MySQL query statement below sel ...
- SQL查询每个部门工资前三名的员工信息
--通用sql select deptno, ename, sal from emp e1 where ( ) from emp e2 where e2.deptno=e1.deptno and e2 ...
- 部门工资前三高的所有员工 - LeetCode
Employee 表包含所有员工信息,每个员工有其对应的工号 Id,姓名 Name,工资 Salary 和部门编号 DepartmentId . +----+-------+--------+---- ...
- mysql查询每个部门/班级前几名
Employee 表包含所有员工信息,每个员工有其对应的 Id, salary 和 department Id . +----+-------+--------+--------------+ | I ...
- [SQL]LeetCode184. 部门工资最高的员工 | Department Highest Salary
The Employee table holds all employees. Every employee has an Id, a salary, and there is also a colu ...
- LeetCode:184.部门工资最高的员工
题目链接:https://leetcode-cn.com/problems/department-highest-salary/ 题目 Employee 表包含所有员工信息,每个员工有其对应的 Id, ...
- leetcode 184 部门工资最高的员工
题目描述:Employee 表包含所有员工信息,每个员工有其对应的 Id, salary 和 department Id. Department 表包含公司所有部门的信息. 编写一个 SQL 查询,找 ...
随机推荐
- HDU 4444:Walk(思维建图+BFS)***
http://acm.hdu.edu.cn/showproblem.php?pid=4444 题意:给出一个起点一个终点,给出n个矩形的两个对立顶点,问最少需要拐多少次弯可以从起点到达终点,如果不能输 ...
- RedisDesktopManager远程连接Linux系统的Redis服务
linux下安装redis :https://www.runoob.com/redis/redis-install.html 进入 src 运行redis : ./redis-server 打开另 ...
- 01(b)无约束优化(准备知识)
1.解方程转化为优化问题 $n\left\{ \begin{aligned}& {{P}_{1}}(x)=0 \\ & {{P}_{2}}(x)=0 \\ & \text{ ...
- C语言学习书籍推荐《C程序设计语言(第2版•新版)》下载
克尼汉 (作者), 等 (作者, 译者), 徐宝文 (译者) 下载地址:点我 <C程序设计语言(第2版•新版)>是由C语言的设计者Brian W.Kernighan和Dennis M.Ri ...
- MYSQL千万级别数据量迁移Elasticsearch5.6.1实战
从关系型库中迁移数据算是比较常见的场景,这里借助两个工具来完成本次的数据迁移,考虑到数据量并不大(不足两千万),未采用snapshot快照的形式进行. Elasticsearch-jdbc,Githu ...
- Hash的应用2
代码: #include <stdio.h> #define OFFSET 500000//偏移量 ];//记录每个数是否出现,出现为1,不出现为0 int main(){ int n,m ...
- 详细记录登录过程的用户、IP地址、shell命令以及详细操作时间
将下面的代码添加到/etc/profile #history USER_IP=`>/dev/null|awk '{print $NF}'|sed -e 's/[()]//g'` HISTDIR= ...
- [NOIP2003] 传染病控制题解
问题 F: [NOIP2003] 传染病控制 时间限制: 1 Sec 内存限制: 128 MB 题目描述 [问题背景] 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国大范 ...
- 简易数据分析 06 | 如何导入别人已经写好的 Web Scraper 爬虫
这是简易数据分析系列的第 6 篇文章. 上两期我们学习了如何通过 Web Scraper 批量抓取豆瓣电影 TOP250 的数据,内容都太干了,今天我们说些轻松的,讲讲 Web Scraper 如何导 ...
- 洛谷P3275 [SCOI2011]糖果 题解
题目链接: https://www.luogu.org/problemnew/show/P3275 分析: 本题就是一个裸的差分约束. 核心: x=1x=1x=1时,a=b,a−>b,b−> ...