row_number的用途非常廣泛滞乙,排序最好用它,它會(huì)為查詢出來(lái)的每一行記錄生成一個(gè)序號(hào)鉴嗤,依次排序且不會(huì)重復(fù)斩启,注意使用row_number函數(shù)時(shí)必須要用over子句選擇對(duì)某一列進(jìn)行排序才能生成序號(hào)。
rank函數(shù)用于返回結(jié)果集的分區(qū)內(nèi)每行的排名醉锅,行的排名是相關(guān)行之前的排名數(shù)加一兔簇。簡(jiǎn)單來(lái)說(shuō)rank函數(shù)就是對(duì)查詢出來(lái)的記錄進(jìn)行排名,與row_number函數(shù)不同的是硬耍,rank函數(shù)考慮到了over子句中排序字段值相同的情況垄琐,如果使用rank函數(shù)來(lái)生成序號(hào),over子句中排序字段值相同的序號(hào)是一樣的经柴,后面字段值不相同的序號(hào)將跳過(guò)相同的排名號(hào)排下一個(gè)狸窘,也就是相關(guān)行之前的排名數(shù)加一,可以理解為根據(jù)當(dāng)前的記錄數(shù)生成序號(hào)坯认,后面的記錄依此類推翻擒。
dense_rank函數(shù)的功能與rank函數(shù)類似,dense_rank函數(shù)在生成序號(hào)時(shí)是連續(xù)的牛哺,而rank函數(shù)生成的序號(hào)有可能不連續(xù)陋气。dense_rank函數(shù)出現(xiàn)相同排名時(shí),將不跳過(guò)相同排名號(hào)荆隘,rank值緊接上一次的rank值恩伺。在各個(gè)分組內(nèi),rank()是跳躍排序椰拒,有兩個(gè)第一名時(shí)接下來(lái)就是第四名晶渠,dense_rank()是連續(xù)排序凰荚,有兩個(gè)第一名時(shí)仍然跟著第二名。
借助實(shí)例能更直觀地理解:
假設(shè)現(xiàn)在有一張學(xué)生表student褒脯,學(xué)生表中有姓名便瑟、分?jǐn)?shù)、課程編號(hào)番川。
select * from student;
現(xiàn)在需要按照課程對(duì)學(xué)生的成績(jī)進(jìn)行排序:
--row_number() 順序排序
select name,course,row_number() over(partition by course order by score desc) rank from student;
--rank() 跳躍排序到涂,如果有兩個(gè)第一級(jí)別時(shí),接下來(lái)是第三級(jí)別
select name,course,rank() over(partition by course order by score desc) rank from student;
dense_rank() 連續(xù)排序颁督,如果有兩個(gè)第一級(jí)別時(shí)践啄,接下來(lái)是第二級(jí)別
select name,course,dense_rank() over(partition by course order by score desc) rank from student;</pre>
取得每門課程的第一名:
--每門課程第一名只取一個(gè):
select * from (select name,course,row_number() over(partition by course order by score desc) rank from student) where rank=1; --每門課程第一名取所有:
select * from (select name,course,dense_rank() over(partition by course order by score desc) rank from student) where rank=1; --每門課程第一名取所有:
select * from (select name,course,rank() over(partition by course order by score desc) rank from student) where rank=1;
附:每門課程第一名取所有的其他方法(使用group by 而不是partition by):
select s.* from student sinner join(select course,max(score) as score from student group by course) con s.course=c.course and s.score=c.score; --或者使用using關(guān)鍵字簡(jiǎn)化連接
select ***** from student sinner join(select course,max(score) as score from student group by course) c
using(course,score);
關(guān)于Parttion by:
Parttion by關(guān)鍵字是Oracle中分析性函數(shù)的一部分,用于給結(jié)果集進(jìn)行分區(qū)沉御。它和聚合函數(shù)Group by不同的地方在于它只是將原始數(shù)據(jù)進(jìn)行名次排列屿讽,能夠返回一個(gè)分組中的多條記錄(記錄數(shù)不變),而Group by是對(duì)原始數(shù)據(jù)進(jìn)行聚合統(tǒng)計(jì)吠裆,一般只有一條反映統(tǒng)計(jì)值的結(jié)果(每組返回一條)伐谈。
TIPS:
使用rank over()的時(shí)候,空值是最大的试疙,如果排序字段為null, 可能造成null字段排在最前面诵棵,影響排序結(jié)果。
可以這樣: rank over(partition by course order by score desc nulls last)
總結(jié):
在使用排名函數(shù)的時(shí)候需要注意以下三點(diǎn):
1祝旷、排名函數(shù)必須有 OVER 子句履澳。
2、排名函數(shù)必須有包含 ORDER BY 的 OVER 子句缓屠。
3奇昙、分組內(nèi)從1開(kāi)始排序。
轉(zhuǎn)載自:
https://www.cnblogs.com/qiuting/p/7880500.html