题目

查询部门工资前三高的员工。

我用的数据库是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. 部门工资前三高的员工的更多相关文章

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

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

  2. sql查询:部门工资前三高的员工和部门工资最高的员工

    创建表:Create table If Not Exists Employee (Id int, Name varchar(255), Salary int, DepartmentId int);Cr ...

  3. 185. 部门工资前三高的所有员工 + 多表联合 + join + dense_rank()

    185. 部门工资前三高的所有员工 LeetCode_MySql_185 题目描述 方法一:使用join on # Write your MySQL query statement below sel ...

  4. SQL查询每个部门工资前三名的员工信息

    --通用sql select deptno, ename, sal from emp e1 where ( ) from emp e2 where e2.deptno=e1.deptno and e2 ...

  5. 部门工资前三高的所有员工 - LeetCode

    Employee 表包含所有员工信息,每个员工有其对应的工号 Id,姓名 Name,工资 Salary 和部门编号 DepartmentId . +----+-------+--------+---- ...

  6. mysql查询每个部门/班级前几名

    Employee 表包含所有员工信息,每个员工有其对应的 Id, salary 和 department Id . +----+-------+--------+--------------+ | I ...

  7. [SQL]LeetCode184. 部门工资最高的员工 | Department Highest Salary

    The Employee table holds all employees. Every employee has an Id, a salary, and there is also a colu ...

  8. LeetCode:184.部门工资最高的员工

    题目链接:https://leetcode-cn.com/problems/department-highest-salary/ 题目 Employee 表包含所有员工信息,每个员工有其对应的 Id, ...

  9. leetcode 184 部门工资最高的员工

    题目描述:Employee 表包含所有员工信息,每个员工有其对应的 Id, salary 和 department Id. Department 表包含公司所有部门的信息. 编写一个 SQL 查询,找 ...

随机推荐

  1. 【名额有限】云开发AI拓展能力等你来体验!

    这次来了个超厉害的新能力! 人脸智能打马赛克.人脸智能裁剪--各种操作,都能一步到位! 迫不及待想体验,戳链接:https://wj.qq.com/s2/3986990/e0ef/ 还没有搞懂,继续往 ...

  2. Ural 2064:Caterpillars(思维暴力)

    http://acm.timus.ru/problem.aspx?space=1&num=2064 题意:有n只虫子在爬树,每个虫子往上爬ti距离后会往下掉落ti距离,每爬一个单位距离耗费一个 ...

  3. 我的那些年(12)~公司技术转行,我也跟着转到java了

    回到目录 我的那些年(12)~公司技术转行,我也跟着转到java了 CTO换人了 微软技术栈不被认可经常被喷 技术统一向java转 换了mac book后,docker还是很占内存 学习springb ...

  4. python generator与coroutine

    python  generator与coroutine 协程 简单介绍 协程,又称微线程,纤程,英文名Coroutine.协程是一种用户态的轻量级线程,又称微线程.协程拥有自己的寄存器上下文和栈,调度 ...

  5. JVM(八):Java 对象模型

    JVM(八):Java 对象模型 本文将学习对象是如何创建的,对象的内存布局,以及如何定位访问一个对象. 对象创建 当虚拟机碰到一个new指令时,首先检查指令参数能否在常量池中定位一个类的符号引用,并 ...

  6. linux修改时间显示格式

    1. 问题描述 Linux下经常使用 "ls - ll"命令查看文件夹或文件创建及权限信息,但是满屏的Mar .May.Jul有点小难受. 2. 解决方案 修改bash_profi ...

  7. 20131222-Dom省市加载-第二十七天

    [1]省市选择 <head> <title></title> <script type="text/javascript"> win ...

  8. Windows OS添加USB3.0驱动!

    原因:现在的win7.win2008等一些早期的系统在安装时无法使USB鼠标和键盘... 1.  素材(dism64工具.UltraISO工具.U盘一个) 2.  先使用UltrISO工具制作一个wi ...

  9. Vue状态管理之Bus

    一般在项目中,状态管理都是使用Vue官方提供的Vuex 当在多组件之间共享状态变得复杂时,使用Vuex,此外也可以使用Bus来进行简单的状态管理 1.1 父组件与子组件之间的通信 vue.config ...

  10. php常用实用函数整理

    1.PHP加密解密 PHP加密和解密函数可以用来加密一些有用的字符串存放在数据库里,并且通过可逆解密字符串,该函数使用了base64和MD5加密和解密. function encryptDecrypt ...