mysql分组查询各组前几的数据

题目类型:MySql

力扣上的一道算法题,也是看了评论区的大神解析后才知晓怎么做。可以拓展为分组查询前几的数据。

问题:

有两张表,一张员工表(Employee),一张部门表(Department),查各个部门前三的薪资的部门名字+员工信息

自己的想法:

①先按照各个部门进行分组,再在各个部门中按照薪水进行排序,最后再找出各个部门中薪资排名前三的数据
②实现

select Department, Employee, Salary
from(
    select d.Name Department, e.Name Employee, e.Salary as Salary,
        dense_rank() over ( partition by DepartmentId order by Salary desc) r
    from Employee as e, Department as d where d.Id = e.DepartmentId) t 
where r<=3;

③后面我也用其他的函数试了一下,发现(以上面sql语句进行测试)

/**
*	排序函数,它是在每一条数据前加上一个序号,
*	缺点:若是出现相同的数据的情况就会出现问题,因为只获取到前三条数据
*	假设薪资前三的数据是 9000(1) 8500(2) 8500(3) 7000(4) 只获取了前三条
*/
row_number()  
/**
*	rank的排序方式是如果出现薪资相同的情况下,它们排序数字是一样的
*	假设薪资前三的数据是 9000(1) 8500(2) 8500(2) 7000(4) 
*	因为rank是跳跃式的排序方式,所以还是会出现问题
*/
rank()
/**
*	dense_rank的排序方式和rank差不多,区别就是它的排序是连续性的
*	假设薪资前三的数据是 9000(1) 8500(2) 8500(2) 7000(3) 
*/
dense_rank()
/**
*	这个函数可以理解成分区或者分组,但是我感觉好像有点像随机的
*	NTILE(1) 将查询到的数据分为同一个区 1
*	NTILE(2) 将查询到的数据分为两个区 1 2
*/
NTILE()

分享:

分享一个大佬的做法:
①找出各个部门的前三个,也就是说部门id一样,然后薪资大于某一个薪资的只有两个,加上这个“某一个”就是三个。先查找出这三个薪资的id集。此处有一个关键点就是去重,而且去重是得去掉薪水重复的,但是其实id是没有被去掉的。

select e1.Id from Employee e1 left join Employee e2 on e1.DepartmentId = e2.DepartmentId and e1.Salary<e2.Salary group by e1.Id having count(distinct e2.Salary)<=2

②将①中查询获取的id集进行查询即可,此处记得对比department的id需要在部门表中存在,因为测试用例中可能存在部门表中并没有部门信息存在,导致报错。其中根据部门id进行升序,按照薪水进行降序

select d.Name Department,e.Name Employee,e.Salary Salary from Employee e left join Department d on e.DepartmentId = d.Id  where e.Id in 
()
and e.DepartmentId in (select Id from Department) order by d.Id asc,e.Salary desc
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jz_Stu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值