一、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():返回的
相關等級會跳躍


SELECT empno,sal,
rank() over(order by sal) rank,
dense_rank() over(order by sal) dense_rank,
row_number() over(order by sal) row_number
FROM emp;

mysql實現方式:
SET @rk=0;
SET @deptno=0;
SELECT ename,
sal,
@rk:=IF(@deptno=deptno,@rk+1,1) rk,
@deptno:=deptno deptno
FROM emp
ORDER BY deptno,sal DESC;
二、RANK()的用法
語法:RANK() OVER (PARTITION BY COL1 ORDER BY COL2)
RANK()的用法和ROW_NUMBER()類似,只不過RANK()是跳躍排序,例如:有兩個第三名時接下來就是第五名(同樣是在各個分組內)。
SELECT empno,sal,
rank() over(order by sal desc) rank
FROM emp;

上表例子中所用的表為Oracle中自帶的數據表emp,如使用rank()函數排序的結果可以看出,其按降序(或升序)排名后,是一個跳躍排序的,如上圖中紅框中所示。
SELECT b.empno,b.sal,
(SELECT count(a.sal)
from emp a
WHERE b.sal < a.sal)+1 rk
from emp b
ORDER BY sal desc;
其中,在Mysql中還可以使用如下的語句來實現這個排序:
set @rk=0;
select ename,
@rk:=@rk+1 rk,
sal
from emp
order by sal desc;
------------------------------------------------------------------------
select a.*,
@enum:=IF(@bm=a.deptno,@enum+1,1) enum,
@rank:= case when @bm <> a.deptno then 1
when @xz <> a.sal then @enum
else @rank end rk,
@bm:=a.deptno bm, # 變量初始化
@xz:=a.sal xz
from
(select deptno,empno,sal from emp) a,
(select @bm:=null,@rank:=1,@xz:=null,@enum:=0) b
order by deptno,sal desc
三、DENSE_RANK()的用法
語法:DENSE_RANK() OVER(PARTITION BY COL1 ORDER BY COL2)
DENSE_RANK()的用法和ROW_NUMBER()類似,只不過DENSE_RANK()是連續排序,有兩個第二名時仍然跟着第三名(同樣在各個分組內)。
SELECT empno,sal,
dense_rank() over(order by sal desc) dense_rank
FROM emp;

同上,本函數繼續使用數據表emp。可以看出,dense_rank()對sal進行降序排序后,排序值是連續的。
SELECT b.empno,b.sal,
(SELECT count(distinct a.sal)
from emp a
WHERE b.sal < a.sal)+1 rk
from emp b
ORDER BY sal desc;
此SQL語句同樣可以實現dense_rank()的效果,與rank()中實現的區別在於count()函數中第三部分使用了distinct函數來去重,從而達到了排序值是連續的。
同樣,本案例也可以使用Mysql語句來實現,如下:
set @rk=0;
set @sal=0;
select ename,
@rk:=if(@sal=sal,@rk,@rk+1) rk,
@sal:=sal sal
from emp
order by sal desc;
————————————————
select a.*,
@rank:= case when @bm <> a.deptno then 1
when @xz <> a.sal then @rank+1
else @rank end rk,
@bm:=a.deptno bm, # 變量初始化
@xz:=a.sal xz
from
(select deptno,empno,sal from emp) a,
(select @bm:=null,@rank:=1,@xz:=null) b
order by deptno,sal desc
————————————————
原文鏈接:https://blog.csdn.net/Jason_05/article/details/90743928