postgresql rank() over, dense_rank(), row_number()用法區(qū)別
如下學(xué)生表student,學(xué)生表中有姓名、分?jǐn)?shù)、課程編號,需要按照課程對學(xué)生的成績進(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 () 可以把成績相同的兩名是并列,如下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é)生成績并列不間斷順序排名,如下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 可以把相同成績的連續(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é)果集分組,如果沒有指定,會把整個(gè)結(jié)果集作為一個(gè)分組
rank 、dense_rank 、row_numer 都是不同方式的結(jié)果集組內(nèi)排序,一般都結(jié)合over 字句出現(xiàn),over 字句里 會有 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 排名語法
PostgreSQL 和Oracle 都提供了 row_number() over() 這樣的語句來進(jìn)行對應(yīng)的字段排名,很是方便。MySQL卻沒有提供這樣的語法。
這次我提供的表結(jié)構(gòu)如下,
Table "ytt.t1" Column | Type | Modifiers --------+-----------------------+----------- i_name | character varying(10) | not null rank | integer | not null
我模擬了20條數(shù)據(jù)來做演示。
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下,我們來對這樣的排名函數(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)
第二種:
帶有完整的排名字段但是沒有排序。
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)
第三種:
沒有任何排名字段,也沒有任何排序字段。
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)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
相關(guān)文章
postgresql 實(shí)現(xiàn)查詢出的數(shù)據(jù)為空,則設(shè)為0的操作
這篇文章主要介紹了postgresql 實(shí)現(xiàn)查詢出的數(shù)據(jù)為空,則設(shè)為0的操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01Docker環(huán)境實(shí)現(xiàn)PostgreSQL自動備份的流程步驟
本文詳細(xì)介紹了如何在Ubuntu系統(tǒng)中安裝Docker,然后在Docker容器內(nèi)安裝和配置PostgreSQL數(shù)據(jù)庫,接著,重點(diǎn)講解了如何在PostgreSQL中安裝和配置pg_rman工具,用于數(shù)據(jù)庫的備份和恢復(fù)操作,文章還涵蓋了創(chuàng)建定時(shí)備份任務(wù)以及刪除備份的步驟,需要的朋友可以參考下2024-11-11PostgreSQL時(shí)間日期的語法及注意事項(xiàng)
在開發(fā)過程中,經(jīng)常要取日期的年,月,日,小時(shí)等值,PostgreSQL 提供一個(gè)非常便利的EXTRACT函數(shù),這篇文章主要給大家介紹了關(guān)于PostgreSQL時(shí)間日期的語法及注意事項(xiàng)的相關(guān)資料,需要的朋友可以參考下2023-01-01Postgresql中json和jsonb類型區(qū)別解析
在我們的業(yè)務(wù)開發(fā)中,可能會因?yàn)樘厥狻練v史,偷懶,防止表連接】經(jīng)常會有JSON或者JSONArray類的數(shù)據(jù)存儲到某列中,這個(gè)時(shí)候再PG數(shù)據(jù)庫中有兩種數(shù)據(jù)格式可以直接一對多或者一對一的映射對象,接下來通過本文介紹Postgresql中json和jsonb類型區(qū)別,需要的朋友可以參考下2024-06-06PostgreSQL截取字符串到指定字符位置詳細(xì)示例
這篇文章主要給大家介紹了關(guān)于PostgreSQL截取字符串到指定字符位置的相關(guān)資料,PostgreSQL數(shù)據(jù)庫拼接字符串函數(shù)是一種非常重要的函數(shù),使用它可以方便地將不同的字符串進(jìn)行拼接操作,從而得到我們需要的結(jié)果,需要的朋友可以參考下2023-07-07使用PostgreSQL數(shù)據(jù)庫建立用戶畫像系統(tǒng)的方法
這篇文章主要介紹了使用PostgreSQL數(shù)據(jù)庫建立用戶畫像系統(tǒng),下面使用一個(gè)具體的例子來說明如何使用PostgreSQL的json數(shù)據(jù)類型來建立用戶標(biāo)簽數(shù)據(jù),需要的朋友可以參考下2022-10-10在PostgreSQL中實(shí)現(xiàn)數(shù)據(jù)的自動清理和過期清理
在 PostgreSQL 中,可以通過多種方式實(shí)現(xiàn)數(shù)據(jù)的自動清理和過期處理,以確保數(shù)據(jù)庫不會因?yàn)榇鎯^多過時(shí)或不再需要的數(shù)據(jù)而導(dǎo)致性能下降和存儲空間浪費(fèi),本文給大家介紹了一些常見的方法及詳細(xì)示例,需要的朋友可以參考下2024-07-07