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 查询,找 ...
随机推荐
- SwiftLint:代码规范检查工具介绍
Swift-CodeStyle Checker:SwiftLint 介绍: SwiftLint 是一个用于强制检查 Swift 代码风格和规定的一个工具,基本上以 GitHub's Swift 代码风 ...
- python logging模块使用总结
目录 logging模块 日志级别 logging.basicConfig()函数中的具体参数含义 format参数用到的格式化信息 使用logging打印日志到标准输出 使用logging.base ...
- hihoCoder 1308:搜索二·骑士问题(BFS预处理)
题目链接 题意 中文题意. 思路 对于每一个骑士,可以先预处理出到达地图上某个点的需要走的步数,然后最后暴力枚举地图上每一个点,让三个骑士走过的距离之和最小即可. #include <bits/ ...
- TCP中的粘包问题,以及用TCP和UDP实现多次聊天
TCP协议 在连接内多和客户端说几句 #server端 import socket sk = socket.socket() sk.bind(('127.0.0.1',9001)) sk.listen ...
- 职业生涯之完成OCM考试后的感想
背景知识:关于OCM认证,百科是这样描述的: Oracle Certified Master(OCM) 大师认证资质是Oracle认证的最高级别.此认证是对技术.知识和操作技能的最高级别的认可.Ora ...
- C语言实现—学生成绩管理系统(Linux下运行)
开发环境:Linux 开发语言:C 相关文件下载: 码云:https://gitee.com/ikaros-521/c_project/tree/master/%E5%AD%A6%E7%94%9F%E ...
- win10win7office系列激活工具 KMSAuto Net 2016 v1.5.4 绿色便携版
下载地址:点我 KMSpico又称KMS激活工具,KMSpico是目前成功且经常更新的Windows激活工具,可以激活任何版本的window系统和任何版本的Office软件,即使是win8和offic ...
- NetCore + Mysql CodeFirst 生成数据库
首先定义领域的模型类,然后配置下面的一些东西,最后执行类 1. 新建Context 继承自 DbContext public class EFProjectContext : DbContext { ...
- 从URL获取图片并保存到本地
/// <summary> /// HttpWebRequest Property /// </summary> /// <param name="fileNa ...
- MYSQL手工注入(详细步骤)—— 待补充
0x00 SQL注入的分类: (1)基于从服务器接收到的响应 ▲基于错误的 SQL 注入 ▲联合查询的类型 ▲堆查询注射 ▲SQL 盲注 ...