当前位置:   article > 正文

Oracle中排序函数的用法之ROW_NUMBER()/RANK()/DENSE_RANK() OVER()的区别_rownumber()over()和rank的区别

rownumber()over()和rank的区别

一、ROW_NUMBER()的用法

语法:ROW_NUMBER() OVER(PARTITION BY COLUMN ORDER BY COLUMN)

row_number()从1开始,为每一条分组记录返回一个数字,这里的ROW_NUMBER() OVER (ORDER BY colum DESC) 是先把colum列降序,再为降序以后的每条colum记录返回一个序号。

ROW_NUMBER() OVER (PARTITION BY COL1 ORDER BY COL2) 表示根据COL1分组,在分组内部根据 COL2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的,没有重复值)。

row_number():返回的是行信息,没有排名

rank():返回的相关等级不会跳跃

dense_rank():返回的相关等级会跳跃

  1. SELECT empno,sal,
  2. rank() over(order by sal) rank,
  3. dense_rank() over(order by sal) dense_rank,
  4. row_number() over(order by sal) row_number
  5. FROM emp;

  1. SET @rk=0;
  2. SET @deptno=0;
  3. SELECT ename,
  4. sal,
  5. @rk:=IF(@deptno=deptno,@rk+1,1) rk,
  6. @deptno:=deptno deptno
  7. FROM emp
  8. ORDER BY deptno,sal DESC;

二、RANK()的用法

语法:RANK() OVER (PARTITION BY COL1 ORDER BY COL2) 

RANK()的用法和ROW_NUMBER()类似,只不过RANK()是跳跃排序,例如:有两个第三名时接下来就是第五名(同样是在各个分组内)。

  1. SELECT empno,sal,
  2. rank() over(order by sal desc) rank
  3. FROM emp;

上表例子中所用的表为Oracle中自带的数据表emp,如使用rank()函数排序的结果可以看出,其按降序(或升序)排名后,是一个跳跃排序的,如上图中红框中所示。

  1. SELECT b.empno,b.sal,
  2. (SELECT count(a.sal)
  3. from emp a
  4. WHERE b.sal < a.sal)+1 rk
  5. from emp b
  6. ORDER BY sal desc;

其中,在Mysql中还可以使用如下的语句来实现这个排序:

  1. set @rk=0;
  2. select ename,
  3. @rk:=@rk+1 rk,
  4. sal
  5. from emp
  6. order by sal desc;
  1. select a.*,
  2. @enum:=IF(@bm=a.deptno,@enum+1,1) enum,
  3. @rank:= case when @bm <> a.deptno then 1
  4. when @xz <> a.sal then @enum
  5. else @rank end rk,
  6. @bm:=a.deptno bm, # 变量初始化
  7. @xz:=a.sal xz
  8. from
  9. (select deptno,empno,sal from emp) a,
  10. (select @bm:=null,@rank:=1,@xz:=null,@enum:=0) b
  11. order by deptno,sal desc

三、DENSE_RANK()的用法

语法:DENSE_RANK() OVER(PARTITION BY COL1 ORDER BY COL2)

DENSE_RANK()的用法和ROW_NUMBER()类似,只不过DENSE_RANK()是连续排序,有两个第二名时仍然跟着第三名(同样在各个分组内)。

  1. SELECT empno,sal,
  2. dense_rank() over(order by sal desc) dense_rank
  3. FROM emp;

同上,本函数继续使用数据表emp。可以看出,dense_rank()对sal进行降序排序后,排序值是连续的。

  1. SELECT b.empno,b.sal,
  2. (SELECT count(distinct a.sal)
  3. from emp a
  4. WHERE b.sal < a.sal)+1 rk
  5. from emp b
  6. ORDER BY sal desc;

此SQL语句同样可以实现dense_rank()的效果,与rank()中实现的区别在于count()函数中第三部分使用了distinct函数来去重,从而达到了排序值是连续的。

同样,本案例也可以使用Mysql语句来实现,如下:

  1. set @rk=0;
  2. set @sal=0;
  3. select ename,
  4. @rk:=if(@sal=sal,@rk,@rk+1) rk,
  5. @sal:=sal sal
  6. from emp
  7. order by sal desc;
  1. select a.*,
  2. @rank:= case when @bm <> a.deptno then 1
  3. when @xz <> a.sal then @rank+1
  4. else @rank end rk,
  5. @bm:=a.deptno bm, # 变量初始化
  6. @xz:=a.sal xz
  7. from
  8. (select deptno,empno,sal from emp) a,
  9. (select @bm:=null,@rank:=1,@xz:=null) b
  10. order by deptno,sal desc

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/240849
推荐阅读
相关标签
  

闽ICP备14008679号