Oracle 分组后取每组第一条数据

From:https://www.cnblogs.com/shined/archive/2013/01/16/2862809.html

为了方便大家学习和测试,所有的例子都是在Oracle自带用户Scott下建立的。

注:标题中的红色order by是说明在使用该方法的时候必须要带上order by。

一、rank()/dense_rank() over(partition by ...order by ...)

现在客户有这样一个需求,查询每个部门工资最高的雇员的信息,相信有一定oracle应用知识的同学都能写出下面的SQL语句:

[sql]  view plain copy
  1. select e.ename, e.job, e.sal, e.deptno  
  2.   from scott.emp e,  
  3.        (select e.deptno, max(e.sal) sal from scott.emp e group by e.deptno) me  
  4.  where e.deptno = me.deptno  
  5.    and e.sal = me.sal;  

在满足客户需求的同时,大家应该习惯性的思考一下是否还有别的方法。这个是肯定的,就是使用本小节标题中rank() over(partition by...)或dense_rank() over(partition by...)语法,SQL分别如下:

[sql]  view plain copy
  1. select e.ename, e.job, e.sal, e.deptno  
  2.   from (select e.ename,  
  3.                e.job,  
  4.                e.sal,  
  5.                e.deptno,  
  6.                rank() over(partition by e.deptno order by e.sal desc) rank  
  7.           from scott.emp e) e  
  8.  where e.rank = 1;  
[sql]  view plain copy
  1. select e.ename, e.job, e.sal, e.deptno  
  2.   from (select e.ename,  
  3.                e.job,  
  4.                e.sal,  
  5.                e.deptno,  
  6.                dense_rank() over(partition by e.deptno order by e.sal desc) rank  
  7.           from scott.emp e) e  
  8.  where e.rank = 1;  

为什么会得出跟上面的语句一样的结果呢?这里补充讲解一下rank()/dense_rank() over(partition by e.deptno order by e.sal desc)语法。
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():  连续排序,如果有两个第一级时,接下来仍然是第二级。



你可能感兴趣的:(Oracle)