Oracle排名rank() dense_rank() row_number() 分区partition by

首先感谢生菜肥羊同学提供的问题和良好的解决方案,再次感谢!

 

一个查询需求,要查询出每个部门中工资排在前2名的员工信息

提供表结构和记录如下,方便大家进行学习

员工表(employee)

 

IDDEPTIDNAMESALARY
11刘德华2000
21张惠妹2500
31谷超2500
42王杰2000
52武力海4000
63张三10000
73李四20000
83王五30000

 

填入记录后,思考这个需求,每个部门我们很容易想到分组group by,前两名,很容易想到是排序order by,容易想到用group by... order by ...来进行查询,但是这个需求是要查询出工资最大的前两名,而不是工资最大的或是工资最小的员工信息,因为group by deptid进行分组后,查询出来的结果只能是group by后面的字段,或是聚合函数(sum、max、min、count、avg等),查询的粒度比较粗,不够精细。就因为是前2名的信息,导致了不能很好的使用group by ... order by ...进行查询,即使能够查询出结果,效率方面也不会非常令人满意!故放弃这种解决方案

 

这里介绍Oracle中的内置函数rank() over(partition by ...order by ...)来解决,rank() over排名函数,partition by分区函数,order by排序函数,特别注意rank() over()中一定要有order by子句,就是一定要在排序的基础上进行排名

 

整个的意思是在分区、排序后的基础上进行排名,这样就能很好解决每个部门工资在前2名的需求了,语句如下

 

select *
  from (select e1.deptid,
               e1.name,
               e1.salary,
               rank() over(partition by e1.deptid order by e1.salary desc) rn
          from employee e1)
 where rn <= 2

 

要提出的一点是,如果出现重复的情况如何处理,大家从查询结果看到了张惠妹和谷超都是排在了第一名,而没有第二名,dense_rank()同样是排名函数,与rank的区别是它能够查询并列后的下一名,换成dense_rank()的查询结果是张惠妹和谷超都是排在了第一名,刘德华排在了第二名。从字面上也很容易理解,dense_rank意思是密集排名

 

另外在介绍函数row_number()分析函数,也可以用row_number()来代替rank()进行查询,row_number()并不会出现并列的情况,即使上面的工资相同,它也会排出一个第一第二来

 

rank、dense_rank、row_number在SQL Server中同样可以使用

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值