溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

rank() over、dense_rank()和 row_number()三者在postgresql中使用有什么不同

發(fā)布時(shí)間:2020-12-29 09:07:05 來(lái)源:億速云 閱讀:238 作者:Leah 欄目:開(kāi)發(fā)技術(shù)

本篇文章為大家展示了 rank() over、dense_rank()和 row_number()三者在postgresql中使用有什么不同,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。

如下學(xué)生表student,學(xué)生表中有姓名、分?jǐn)?shù)、課程編號(hào),需要按照課程對(duì)學(xué)生的成績(jī)進(jìn)行排序

select * from jinbo.student;
 id | name | score | course 
----+-------+-------+--------
 5 | elic | 70 |  1
 4 | dock | 100 |  1
 3 | cark | 80 |  1
 2 | bob | 90 |  1
 1 | alice | 60 |  1
 10 | jacky | 80 |  2
 9 | iris | 80 |  2
 8 | hill | 60 |  1
 7 | grace | 50 |  2
 6 | frank | 70 |  2
 6 | test |  |  2
(11 rows)

1、rank over () 可以把成績(jī)相同的兩名是并列,如下course = 2 的結(jié)果rank值為:1 2 2 4 5

 select name,
  score,
  course,
  rank() over(partition by course order by score desc) as rank
 from jinbo.student;
 name | score | course | rank 
-------+-------+--------+------
 dock | 100 |  1 | 1
 bob | 90 |  1 | 2
 cark | 80 |  1 | 3
 elic | 70 |  1 | 4
 hill | 60 |  1 | 5
 alice | 60 |  1 | 5
 test |  |  2 | 1
 iris | 80 |  2 | 2
 jacky | 80 |  2 | 2
 frank | 70 |  2 | 4
 grace | 50 |  2 | 5
(11 rows)

2、dense_rank()和rank over()很相似,可以把學(xué)生成績(jī)并列不間斷順序排名,如下course = 2 的結(jié)果rank值為:1 2 2 3 4

select name,score,
  course,
  dense_rank() over(partition by course order by score desc) as rank
 from jinbo.student;
 name | score | course | rank 
-------+-------+--------+------
 dock | 100 |  1 | 1
 bob | 90 |  1 | 2
 cark | 80 |  1 | 3
 elic | 70 |  1 | 4
 hill | 60 |  1 | 5
 alice | 60 |  1 | 5
 test |  |  2 | 1
 iris | 80 |  2 | 2
 jacky | 80 |  2 | 2
 frank | 70 |  2 | 3
 grace | 50 |  2 | 4
(11 rows)

3、row_number 可以把相同成績(jī)的連續(xù)排名,如下 course = 2 的結(jié)果rank值為:1 2 3 4 5

select name,score,
  course,
  row_number() over(partition by course order by score desc) as rank
 from jinbo.student;
 name | score | course | rank 
-------+-------+--------+------
 dock | 100 |  1 | 1
 bob | 90 |  1 | 2
 cark | 80 |  1 | 3
 elic | 70 |  1 | 4
 hill | 60 |  1 | 5
 alice | 60 |  1 | 6
 test |  |  2 | 1
 iris | 80 |  2 | 2
 jacky | 80 |  2 | 3
 frank | 70 |  2 | 4
 grace | 50 |  2 | 5
(11 rows)

使用rank over()的時(shí)候,空值是最大的,如果排序字段為null, 可能造成null字段排在最前面,影響排序結(jié)果,可以如下:

rank over(partition by course order by score desc nulls last)

4、總結(jié)

partition by 用于結(jié)果集分組,如果沒(méi)有指定,會(huì)把整個(gè)結(jié)果集作為一個(gè)分組

rank 、dense_rank 、row_numer 都是不同方式的結(jié)果集組內(nèi)排序,一般都結(jié)合over 字句出現(xiàn),over 字句里 會(huì)有 partition by、order by、last、first 的任意組合,如下:

rank() over(partition by a,b order by a, order by b desc);
rank() over(partition by a order by b nulls first)
rank() over(partition by a order by b nulls last)

補(bǔ)充:Oracle或者PostgreSQL的row_number over 排名語(yǔ)法

PostgreSQL 和Oracle 都提供了 row_number() over() 這樣的語(yǔ)句來(lái)進(jìn)行對(duì)應(yīng)的字段排名,很是方便。MySQL卻沒(méi)有提供這樣的語(yǔ)法。

這次我提供的表結(jié)構(gòu)如下,

Table "ytt.t1" 
 Column |   Type   | Modifiers 
--------+-----------------------+----------- 
 i_name | character varying(10) | not null 
 rank | integer    | not null

我模擬了20條數(shù)據(jù)來(lái)做演示。

t_girl=# select * from t1 order by i_name;        
 i_name | rank 
---------+------ 
 Charlie | 12 
 Charlie | 12 
 Charlie | 13 
 Charlie | 10 
 Charlie | 11 
 Lily  | 6 
 Lily  | 7 
 Lily  | 7 
 Lily  | 6 
 Lily  | 5 
 Lily | 7 
 Lily | 4 
 Lucy | 1 
 Lucy | 2 
 Lucy | 2 
 Ytt  | 14 
 Ytt  | 15 
 Ytt  | 14 
 Ytt  | 14 
 Ytt  | 15 
(20 rows)

在PostgreSQL下,我們來(lái)對(duì)這樣的排名函數(shù)進(jìn)行三種不同的執(zhí)行方式1:

第一種:

完整的帶有排名字段以及排序。

t_girl=# select i_name,rank, row_number() over(partition by i_name order by rank desc) as rank_number from t1;  
 i_name | rank | rank_number 
---------+------+------------- 
 Charlie  | 13 |   1 
 Charlie | 12 |   2 
 Charlie | 12 |   3 
 Charlie | 11 |   4 
 Charlie | 10 |   5 
 Lily  | 7 |   1 
 Lily  | 7 |   2 
 Lily  | 7 |   3 
 Lily  | 6 |   4 
 Lily  | 6 |   5 
 Lily  | 5 |   6 
 Lily  | 4 |   7 
 Lucy | 2 |   1 
 Lucy | 2 |   2 
 Lucy | 1 |   3 
 Ytt  | 15 |   1 
 Ytt  | 15 |   2 
 Ytt  | 14 |   3 
 Ytt  | 14 |   4 
 Ytt  | 14 |   5 
(20 rows)

第二種:

帶有完整的排名字段但是沒(méi)有排序。

t_girl=# select i_name,rank, row_number() over(partition by i_name ) as rank_number from t1; 
 i_name | rank | rank_number 
---------+------+------------- 
 Charlie  | 12 |   1 
 Charlie | 12 |   2 
 Charlie | 13 |   3 
 Charlie | 10 |   4 
 Charlie | 11 |   5 
 Lily  | 6 |   1 
 Lily  | 7 |   2 
 Lily  | 7 |   3 
 Lily  | 6 |   4 
 Lily  | 5 |   5 
 Lily  | 7 |   6 
 Lily  | 4 |   7 
 Lucy | 1 |   1 
 Lucy | 2 |   2 
 Lucy | 2 |   3 
 Ytt  | 14 |   1 
 Ytt  | 15 |   2 
 Ytt  | 14 |   3 
 Ytt  | 14 |   4 
 Ytt  | 15 |   5 
(20 rows)

第三種:

沒(méi)有任何排名字段,也沒(méi)有任何排序字段。

t_girl=# select i_name,rank, row_number() over() as rank_number from t1; 
 i_name | rank | rank_number 
---------+------+------------- 
 Lily  | 7 |   1 
 Lucy | 2 |   2 
 Ytt  | 14 |   3 
 Ytt  | 14 |   4 
 Charlie | 12 |   5 
 Charlie | 13 |   6 
 Lily  | 7 |   7 
 Lily  | 4 |   8 
 Ytt  | 14 |   9 
 Lily  | 6 |   10 
 Lucy | 1 |   11 
 Lily  | 7 |   12 
 Ytt  | 15 |   13 
 Lily  | 6 |   14 
 Charlie | 11 |   15 
 Charlie | 12 |   16 
 Lucy | 2 |   17 
 Charlie | 10 |   18 
 Lily  | 5 |   19 
 Ytt  | 15 |   20 
(20 rows)

上述內(nèi)容就是 rank() over、dense_rank()和 row_number()三者在postgresql中使用有什么不同,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI