注释:为了方便大家学习和测试,所有的例子都是在Oracle自带用户Scott下建立的
oracel的高级用法:rank()/dense_rank() over(partition by ...order by ...)
现在客户有这样一个需求,查询每个部门工资最高的雇员的信息
方法一:常用方法
select e.ename, e.job, e.sal, e.deptno from scott.emp e, (select e.deptno, max(e.sal) sal from scott.emp e group by e.deptno) me where e.deptno = me.deptno and e.sal = me.sal;
方法二:rank() over(partition by...order by ...)
select e.ename, e.job, e.sal, e.deptno from (select e.ename, e.job, e.sal, e.deptno, rank() over(partition by e.deptno order by e.sal desc) rank from scott.emp e) e where e.rank = 1;
方法三:dense_rank() over(partition by...order by ...)
select e.ename, e.job, e.sal, e.deptno from (select e.ename, e.job, e.sal, e.deptno, dense_rank() over(partition by e.deptno order by e.sal desc) rank from scott.emp e) e where e.rank = 1;
三个方法结果一致。
over: 在什么条件之上。
partition by e.deptno: 按部门编号划分(分区)。
order by e.sal desc: 按工资从高到低排序(使用rank()/dense_rank() 时,必须要带order by否则非法)
rank()/dense_rank(): 分级
整个语句的意思就是:在按部门划分的基础上,按工资从高到低对雇员进行分级,“级别”由从小到大的数字表示(最小值一定为1)。
那么rank()和dense_rank()有什么区别呢?
rank(): 跳跃排序,如果有两个第一级时,接下来就是第三级。
dense_rank(): 连续排序,如果有两个第一级时,接下来仍然是第二级。
rank()的结果:
ENAME JOB SAL DEPTNO RANK
SCOTT ANALYST 3000.00 20 1
FORD ANALYST 3000.00 20 1
JONES MANAGER 2975.00 20 3
ADAMS CLERK 1100.00 20 4
dense_rank()的结果:
ENAME JOB SAL DEPTNO RANK
SCOTT ANALYST 3000.00 20 1
FORD ANALYST 3000.00 20 1
JONES MANAGER 2975.00 20 2
ADAMS CLERK 1100.00 20 3
rank()第三列序号是3,dense_rank()第三列序号是2