11 部门工资前三高的所有员工
Opened this issue · 0 comments
astak16 commented
题目
找出每个部门获得前三高工资的所有员工
create table employee (
id int primary key auto_increment,
name varchar(255),
salary int,
departmentId int
);
create table department (
id int primary key auto_increment,
name varchar(255)
);
insert into employee (name, salary, departmentId) values
('joe', 85000, 1),
('henry', 80000, 2),
('sam', 60000, 2),
('max', 90000, 1),
('janet', 69000, 1),
('randy', 85000, 1),
('will', 70000, 1);
insert into department(name) values('it'),('sales');
SQL
select department.id, employee.name, employee.salary from (
select te.departmentId, te.salary,
case ①
when @pre=departmentId then @rank:=@rank + 1
when @pre:=departmentId then @rank:=1
end as 排名
from (select @pre:=null, @rank:=0) tt,
(
select departmentId, salary from employee
group by departmentId, salary
order by departmentId, salary desc
) te
) t
inner join department on t.departmentId = department.id
inner join employee on t.departmentId = employee.departmentId
and employee.salary = t.salary and 排名 <= 3
order by t.departmentId, t.salary desc;
解析
- 将
employee
按照departmentId
和salary
进行分组,将这个临时表命名为te
- 使用
case ... when ... then ... end
和变量根据薪水算出排名,将这个临时表命名为t
。 - 使用两次
inner join
分别连接department
和employee
t
表和department
表连接条件是t.departmentId = department.id
t
表和employee
表连接条件是t.departmentId = employee.departmentId and t.salary = employee.salary
②
Tips:
① case
语句中 when
应该是条件,这里为什么用赋值 :=
- 查询第一条数据进入
case
时,when @prev = departmentId then ...
执行的时,此时@prev
为null
不满足条件,所以它就会执行when @prev := departmentId then ...
,此时@prev
为第一条数据的departmentId
由于赋值语句肯定为true
,所以@rank
就为1
- 查询第二条数据进入
case
时,when @prev = departmentId then ...
由于@prev
有值了,下面的when
就不会执行了。 - 查询第三条数据进入
case
时,when @prev = departmentId then ...
,第三条数据的departmentId
是一个新的值,此时不满足@prev = departmentId
,就会进入第二个when @prev := departmentId then ...
将departmentId
的最新值赋值给@prev
- 按照上面步骤直到所有的数据都查询完。
② 这里为什么用 t.salary = employee.salary
而不用 t.name = employee.name
t.salary = employee.salary
作用是确定是同一个用,这里就有个问题,确定同一个人的话,为什么不用 name
做条件呢? 这里是因为 te
按照 salary
和 department
进行分组,不考虑 name
的原因是可能会有两个人的 salary
是一样的,如果在加上 name
的话,就会出现两个 salary
相同的人,排名不一样。
现在给的数据有两个人的 salary
是一样的,可以将其中一个 salary
修改一下,就可以知道结果了。