题目

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

我用的数据库是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. CDH 5.15.2 离线安装

    一.前置准备 1. 基础信息 1.1 机器 机器名 服务 hadoop1 主节点 hadoop2 data.task hadoop3 data.task 1.2 服务版本 服务 版本 cdh 5.15 ...

  2. 阿里云服务器CentOS7.5安装RabbitMQ

    RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件).RabbitMQ服务器是用Erlang语言编写的,而集群和故障转移是构建在开放电信平台框架上的. 为什么 ...

  3. Codeforces 730A:Toda 2(multiset模拟)

    http://codeforces.com/problemset/problem/730/A 题意:有n个人打天梯,想让这n个人的分数相同,每场比赛必须有2-5个人参赛,参赛的人会降低一分,问一个合理 ...

  4. AD域和LDAP协议

    随着我们的习大大上台后,国家在网络信息安全方面就有了很明显的改变!所以现在好多做网络信息安全产品的公司和需要网络信息安全的公司都会提到用AD域服务器来验证,这里就简单的研究了一下! 先简单的讲讲AD域 ...

  5. SpringBoot第二十一篇:整合ActiveMQ

    作者:追梦1819 原文:https://www.cnblogs.com/yanfei1819/p/11190048.html 版权声明:本文为博主原创文章,转载请附上博文链接! 引言   前一章节中 ...

  6. Java项目案例之---开灯(面向对象复习)

    开灯(面向对象复习) 设计一个台灯类(Lamp)其中台灯有灯泡类(Buble)这个属性,还有开灯(on)这个方法 设计一个灯泡类(Buble),灯泡类有发亮的方法 其中有红灯泡类(RedBuble)和 ...

  7. 控制反转&依赖注入

    IoC(Inversion of Control,控制反转).这是spring的核心,贯穿始终.所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系.这是什么 ...

  8. WinForm控件之【ComboBox】

    基本介绍 下拉文本框应用较为广泛,在winfrom控件当中使用设置也是相对的简单,主要用于存在多种选择的单选操作场景. 常设置属性.事件 DataSource:绑定加载项的数据源,设置属性Displa ...

  9. centos 安装Python3 及对应的pip

    安装Python3安装Python依赖:yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqli ...

  10. java.util.LinkedHashMap cannot be cast to

    Jackson转换泛型List出现错误java.util.LinkedHashMap cannot be cast to com.xxx ObjectMapper mapper = new Objec ...