MySQL部门工资最高的员工

编程入门 行业动态 更新时间:2024-10-09 12:35:58

MySQL部门<a href=https://www.elefans.com/category/jswz/34/1769673.html style=工资最高的员工"/>

MySQL部门工资最高的员工

MySQL部门工资最高的员工

  • SQL架构
  • 题目描述
  • 题解
    • 方法:使用 JOIN 和 IN 语句
    • 方法2
    • 方法: GROUP BY 语句
  • 知识点
    • exists 和 in
      • 1.原理
      • 2.分析
      • 3.总结
      • 4.效率
      • 5.举例说明

SQL架构

Create table If Not Exists Employee (Id int, Name varchar(255), Salary int, DepartmentId int);
Create table If Not Exists Department (Id int, Name varchar(255));insert into Employee (Id, Name, Salary, DepartmentId) values ('1', 'Joe', '70000', '1');
insert into Employee (Id, Name, Salary, DepartmentId) values ('2', 'Jim', '90000', '1');
insert into Employee (Id, Name, Salary, DepartmentId) values ('3', 'Henry', '80000', '2');
insert into Employee (Id, Name, Salary, DepartmentId) values ('4', 'Sam', '60000', '2');
insert into Employee (Id, Name, Salary, DepartmentId) values ('5', 'Max', '90000', '1');insert into Department (Id, Name) values ('1', 'IT');
insert into Department (Id, Name) values ('2', 'Sales');

题目描述

Employee 表包含所有员工信息,每个员工有其对应的 Id, salary 和 department Id。

+----+-------+--------+--------------+
| Id | Name  | Salary | DepartmentId |
+----+-------+--------+--------------+
| 1  | Joe   | 70000  | 1            |
| 2  | Jim   | 90000  | 1            |
| 3  | Henry | 80000  | 2            |
| 4  | Sam   | 60000  | 2            |
| 5  | Max   | 90000  | 1            |
+----+-------+--------+--------------+

Department 表包含公司所有部门的信息。

+----+----------+
| Id | Name     |
+----+----------+
| 1  | IT       |
| 2  | Sales    |
+----+----------+

编写一个 SQL 查询,找出每个部门工资最高的员工。对于上述表,您的 SQL 查询应返回以下行(行的顺序无关紧要)。

+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT         | Max      | 90000  |
| IT         | Jim      | 90000  |
| Sales      | Henry    | 80000  |
+------------+----------+--------+

解释:

Max 和 Jim 在 IT 部门的工资都是最高的,Henry 在销售部的工资最高。

题解

方法:使用 JOIN 和 IN 语句

算法

因为 Employee 表包含 Salary 和 DepartmentId 字段,我们可以以此在部门内查询最高工资。

SELECTDepartmentId, MAX(Salary)
FROMEmployee
GROUP BY DepartmentId;

注意:有可能有多个员工同时拥有最高工资,所以最好在这个查询中不包含雇员名字的信息。

+--------------+-------------+
| DepartmentId | MAX(Salary) |
+--------------+-------------+
|            1 |       90000 |
|            2 |       80000 |
+--------------+-------------+
2 rows in set (0.00 sec)

然后,我们可以把表 Employee 和 Department 连接,再在这张临时表里用 IN 语句查询部门名字和工资的关系。

SELECTDepartment.name AS 'Department',Employee.name AS 'Employee',Salary
FROMEmployeeJOINDepartment ON Employee.DepartmentId = Department.Id
WHERE(Employee.DepartmentId , Salary) IN(   SELECTDepartmentId, MAX(Salary)FROMEmployeeGROUP BY DepartmentId);
+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT         | Jim      |  90000 |
| Sales      | Henry    |  80000 |
| IT         | Max      |  90000 |
+------------+----------+--------+
3 rows in set (0.00 sec)

方法2

select bb.Name as Department, aa.Employee, aa.Salary
from (
select a.Id,a.Name as Employee,a.Salary,a.DepartmentIdfrom Employee ajoin (select DepartmentId, max(Salary) as max_salfrom Employeegroup by DepartmentId) b on a.DepartmentId = b.DepartmentId and a.Salary = b.max_sal
) aa
join Department bb on aa.DepartmentId = bb.Id;
+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT         | Jim      |  90000 |
| Sales      | Henry    |  80000 |
| IT         | Max      |  90000 |
+------------+----------+--------+
3 rows in set (0.01 sec)

方法: GROUP BY 语句

SELECTDepartment.NAME AS Department,Employee.NAME AS Employee,Salary 
FROMEmployee,Department 
WHEREEmployee.DepartmentId = Department.Id AND ( Employee.DepartmentId, Salary ) IN (SELECT DepartmentId, max( Salary ) FROM Employee GROUP BY DepartmentId );+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT         | Jim      |  90000 |
| Sales      | Henry    |  80000 |
| IT         | Max      |  90000 |
+------------+----------+--------+
3 rows in set (0.00 sec)SELECT D.Name AS Department,E1.Name AS Employee,E1.SalaryFROM Employee AS E1INNER JOIN Department AS DON E1.DepartmentId = D.IdWHERE NOT EXISTS (SELECT * FROM Employee AS E2WHERE E1.DepartmentId = E2.DepartmentIdAND E1.Salary < E2.Salary);

知识点

exists 和 in

1.原理

通过使用 EXISTS,Oracle会首先检查主查询,然后运行子查询直到它找到第一个匹配项,
这就节省了时间。

Oracle在执行IN子查询时,首先执行子查询,并将获得的结果列表存放在一个加了索引的临时表中。

在执行子查询之前,系统先将主查询挂起,待子查询执行完毕,存放在临时表中以后再执行主查询。

这也就是使用EXISTS比使用IN通常查询速度快的原因。

2.分析

in 是把外表和内表作hash 连接,而exists是对外表作loop循环。

每次loop循环再对内表进行查询not exists:做NLL,对子查询先查,有个虚表,有确定值,所以就算子查询有NULL最终也有值返回not in:做hash,对子查询表建立内存数组,用外表匹配,那子查询要是NULL那外表没的匹配最终无值返回。

一直以来认为exists比in效率高的说法是不准确的。

但是,如果查询的两个表大小相当,那么用in和exists差别不大。

3.总结

外表大,用IN;内表大,用EXISTS。

4.效率

- select * from T1 where exists(select 1 from T2 where T1.a=T2.a) ;T1数据量小而T2数据量非常大时,T1<<T2 时,1) 的查询效率高。
- select * from T1 where T1.a in (select T2.a from T2);T1数据量非常大而T2数据量小时,T1>>T2 时,2) 的查询效率高。

5.举例说明

例如:表A(小表),表B(大表) 1: select * from A where cc in (select cc from B) 效率低,用到了A表上cc列的索引; select * from A where exists(select cc from B where cc=A) 效率高,用到了B表上cc列的索引。2. select * from B where cc in (select cc from A) 效率高,用到了B表上cc列的索引; select * from B where exists(select cc from A where cc=B) 效率低,用到了A表上cc列的索引。

更多推荐

MySQL部门工资最高的员工

本文发布于:2024-02-28 01:11:03,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1767414.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:工资   员工   部门   MySQL

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!