题目描述
Employee
表包含所有员工信息,每个员工有其对应的 Id, salary 和 department Id。
Employee
表:
Id | Name | Salary | DepartmentId |
---|---|---|---|
1 | Joe | 70000 | 1 |
2 | Jim | 90000 | 1 |
3 | Henry | 80000 | 5 |
4 | Sam | 60000 | 5 |
5 | Max | 90000 | 1 |
Department
表包含公司所有部门的信息。
Department
表:
Id | Name |
---|---|
1 | IT |
2 | Sales |
编写一个 SQL 查询,找出每个部门工资最高的员工。对于上述表,您的 SQL 查询应返回以下行(行的顺序无关紧要)。
Department | Employee | Salary |
---|---|---|
IT | Max | 90000 |
IT | Jim | 90000 |
Sales | Henry | 80000 |
相关知识
此题不需要前置知识
解题过程
-
分析题意
- 将Department表和Employee表进行内连接,条件为Employee.DeparmentId=Deparment.Id
- 按部门分组,每组内进行并列连续排名
- 将每个组内并列第一的所有人的Department、Employee、Salary进行输出
-
根据178分数排名的解题经验,编写sql
SELECT DepartmentName AS Department, `Name` AS Employee, Salary FROM ( SELECT Employee.ID, Employee.`Name`, Salary, DepartmentId, Department.`Name` AS DepartmentName, DENSE_RANK() OVER(PARTITION BY DepartmentId ORDER BY Salary DESC) AS rank_ FROM Employee,Department WHERE Employee.DepartmentId=Department.Id ) u WHERE rank_=1
-
提交,运行通过
-
阅读题解,发现其他人有别的写法
-
先对DepartmentId分组查询最大值,得到不同DepartmentId下的最大值
-
再根据DepartmentId字段连接Department表,连接条件为Employee.DepartmentId=Department.Id
-
对连接后的表进行筛选,保证每个元组的DepartmentId和Salary在第一次求出的最大值里
-
sql
SELECT Department.`Name` AS Department, Employee.`Name` AS Employee, Salary FROM Employee JOIN Department ON Employee.DepartmentId=Department.Id WHERE (DepartmentId,Salary) IN ( SELECT DepartmentId, MAX(Salary) AS MaxSalary FROM Employee GROUP BY DepartmentId )
-
学习总结
-
此题主要考察外连接,外连接中使用了一个关键字ON,设定连接条件,所以再加上WHERE实际上进行了两次筛选。
-
最大值函数:MAX(列名)
-
最小值函数:MIN(列名)
-
如果要校验几个字段在某个集合中,这个几个字段需要用括号括起来,否则会有语法错误
(DepartmentId,Salary) IN ......