mysql组内排序(部门工资前三高的所有员工)

本文介绍了两种在MySQL中获取每个部门工资前三名员工的方法。第一种是利用分组序号,通过定义自变量进行部门内排序并筛选;第二种是使用子查询,先找出全公司排名前三的工资,再进行部门关联查询。虽然子查询方式更易理解,但效率较低。

两种解法 子查询和分组序号

在这里插入图片描述

在这里插入图片描述

1.分组序号,思路:
表关联查询,先按部门分组,按工资排序。

select d.name as Department,e.name as Employee,Salary from Employee e 
 join Department d on  e.DepartmentId=d.id 
group by DepartmentId,e.id order by DepartmentId,Salary Desc

这个时候我们要将分组排序后的前三个取出来,而且工资相同的排名也要相同,也要取出来。

那么需要定义三个自变量,
一个用于定义顺序
一个用于保存上一行的部门,用于判断部门,如果部门不同就要重置序号为1
一个用于保存上一行的工资,如果工资相同 序号就不增加

最后就可以按nu m筛选取出来nu m<=3的数据了。


select Department,Employee,Salary from 
(
select if(@last!=Department,@num:=1,@num:=@num+if(@lastSalary=Salary,0,1)) as num,
Department,Employee,Salary,
@last:=Department as lastDepartment,@lastSalary:=Salary as lastSalary 
 from 
(select d.name as Department,e.name as Employee,Salary from Employee e 
 join Department d on  e.DepartmentId=d.id 
group by DepartmentId,e.id order by DepartmentId,Salary Desc )  a,
(select @last:=null,@lastSalary:=null,@num:=0)  b  group by Department,Employee order by Department,Salary Desc 
) tmp where num<=3

2.子查询

先查询 全公司排名前三的工资

查询出来的结果是 e1 工资里面 比e2 工资小不超过三个的数据行, 其实也就是排名前三的工资。

select e1.Name,e1.Salary,e1.DepartmentId from Employee e1 where 
(
    select count(distinct Salary) from Employee e2 where e1.Salary<e2.Salary
) <3

如果要取部门前三的,则关联条件中再加上 部门id

select e1.Name,e1.Salary,e1.DepartmentId from Employee e1 where 
(
    select count(distinct Salary) from Employee e2 
    where e1.Salary<e2.Salary  and  e1.DepartmentId= e2.DepartmentId
) <3

然后

然后关联部门,按部门排序即可

select d.Name as Department, Employee,Salary from 

(select e1.Name as Employee ,e1.Salary,e1.DepartmentId from Employee e1 where 
(
    select count(distinct Salary) from Employee e2 where e1.Salary<e2.Salary and  e1.DepartmentId= e2.DepartmentId
) <3   ) a  
join Department  d 
on(a.DepartmentId=d.id)  order by DepartmentId

这个写起来简单 但是比较难理解,而且效率低于分组按序号筛选的方式。

理解过程如下:

DISTINCT 字段名 过滤字段中的重复记录
我们先找出公司里前 3 高的薪水,意思是不超过三个值比这些值大

SELECT e1.Salary 
FROM Employee AS e1
WHERE 
		(SELECT  count(DISTINCT e2.Salary) 
		 FROM	Employee AS e2 
	 	 WHERE	e1.Salary < e2.Salary 	AND e1.DepartmentId = e2.DepartmentId) <3



举个栗子:
当 e1 = e2 = [4,5,6,7,8]

e1.Salary = 4,e2.Salary 可以取值 [5,6,7,8],count(DISTINCT e2.Salary) = 4

e1.Salary = 5,e2.Salary 可以取值 [6,7,8],count(DISTINCT e2.Salary) = 3

e1.Salary = 6,e2.Salary 可以取值 [7,8],count(DISTINCT e2.Salary) = 2

e1.Salary = 7,e2.Salary 可以取值 [8],count(DISTINCT e2.Salary) = 1

e1.Salary = 8,e2.Salary 可以取值 [],count(DISTINCT e2.Salary) = 0

最后 3 > count(DISTINCT e2.Salary),所以 e1.Salary 可取值为 [6,7,8],即集合前 3 高的薪水

再把表 Department 和表 Employee 连接,获得各个部门工资前三高的员工。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值