Leetcode的SQL题解:185. 部门工资前三高的员工
2019-07-04 16:53
148 查看
题目
查询部门工资前三高的员工。
我用的数据库是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. 部门工资前三高的员工
- 【leetcode】部门工资前三高的员工
- leetcode练习题-mysql:185. 部门工资前三高的员工
- LeetCode之部门工资前三高的员工
- 【SQL】求得工资在部门平均工资之上得员工
- LeetCode(184)-部门工资最高的员工
- 用一个SQL语句选出每个部门工资最高的员工
- 一句sql 在所有部门中选择平均工资最高的部门所有员工
- 员工部门工资SQL面试题
- 【leetcode】求部门工资最高的员工
- leetcode练习题-mysql:184. 部门工资最高的员工
- 员工部门工资SQL面试题
- SQL(收藏)查询每个部门工资前三名的员工信息
- 部门工资最高的员工
- 一道关于员工与部门查询的SQL笔试题
- oracle--查询本部门薪水大于平均工资的员工
- SQL查询--列出至少有一个员工的部门
- 有一张员工表,有员工名称,部门编号,工资收入,查询每个部门中收入前三的人员清
- 为10号部门的员工涨工资
- [数据库]关于三个比较典型的数据库试题(1.找到员工表中工资最高的前三名;2.找到员工表中薪水大于本部门平均薪水的员工;3.统计每年入职的员工个数)