rank/dense_rank/row_number

三者的區(qū)別:


image.png

關(guān)于變量和if實現(xiàn)rank

SELECT s.score,
@rank_counter := @rank_counter + 1 連續(xù)排名,
IF(@pre_score = s.score, @cur_rank, @cur_rank := @rank_counter) ranking,
@pre_score := s.score
FROM score s, (SELECT @cur_rank :=0, @pre_score := NULL, @rank_counter := 0) r
ORDER BY s.score DESC;

邏輯:
要明白rank的排序邏輯把敢,如果是相同的數(shù)值钞楼,則并列排序,如果后面的值開始不一樣蒸眠,則跳躍排序漾橙,及1,1,3。那么有兩個地方需要注意:1楞卡、并列排序時霜运,讓排序值ranking保持不變,2蒋腮、跳躍排序時淘捡,讓ranking為該數(shù)字在正常排名的位置,及row_number的那個位置池摧。
那么在代碼里焦除,from中設(shè)置的三個變量:1、@cur_rank是實現(xiàn)并列排序和跳躍排序兩者的作彤,也即在rank開窗函數(shù)中最終實現(xiàn)的排名膘魄,2、@pre_score為上一段的得分竭讳,把他放在if的后面進行:=s.score的賦值创葡,比if里面的判斷=s.score慢一步,就是為了讓@pre_score等于上一段的分數(shù)绢慢,好來判斷是否為并列排序灿渴,3、@rank_counter在這里被賦值為0呐芥,然后在select的第一個是@rank_counter:=@rank_counter+1逻杖,也就是給score的每一個分數(shù)都給一個連續(xù)排名,相當(dāng)于row_number思瘟,他在這里的作用是為了給rank進行跳躍時得到他本來所處的位置數(shù)字荸百。
執(zhí)行完from中的代碼以后,開始執(zhí)行select滨攻,注意order by是在select的后面執(zhí)行的够话,但是賦值一直都是最后執(zhí)行的,所以這段代碼里光绕,想篩選出score以后女嘲,進行order by排序,然后再進行相應(yīng)的賦值诞帐。
在if函數(shù)里欣尼,第一步,@pre_score為null,不等于score的第一個值99愕鼓,所以為假钙态,執(zhí)行@cur_rank:=@rank_counter,得到1菇晃,然后再if的后面册倒,@pre_score被賦值為score,此時@pre_score=99磺送;第二步驻子,@pre_score的98不等于score的98,為假估灿,繼續(xù)得到@cur_rank:=@rank_counter,得到2崇呵,同樣第三步得到3,到了第四步馅袁,得到4演熟,重點第5步,此時@pre_score=上一段的分數(shù)等于89司顿,判斷時,@pre_score也是等于此時這一段的score的89時兄纺,為真大溜,返回@cur_rank,為4,這樣按照同樣的邏輯向后執(zhí)行估脆。


image.png

想明白它的邏輯钦奋,再設(shè)計相應(yīng)變量來實現(xiàn)目的。

對于下表進行相關(guān)計算疙赠。


image.png

一付材、不分組的情況下的rank/dense_rank/row_number
1、(1)連續(xù)排名row_number() over(order by)
對表中的所有的分數(shù)進行位置排名圃阳,沒有并列名次的情況

SELECT
    score,
    row_number ( ) over ( ORDER BY score DESC ) ranking 
FROM
    score;

(2)利用變量@和if來實現(xiàn)上面的開窗函數(shù)

SELECT
    score,
    @i := @i + 1 ranking 
FROM
    score,
    ( SELECT @i := 0 ) ranking 
ORDER BY
    score DESC;
image.png

2厌衔、(1)并列跳躍排名rank() over(order by)

SELECT
    score,
    rank ( ) over ( ORDER BY score DESC ) ranking 
FROM
    score;

(2)利用變量@和if來實現(xiàn)上面的開窗函數(shù)
思路:如果分數(shù)一樣,則排名相同捍岳,如果后面的分數(shù)不同富寿,則排名為該值在該表中本來的排名位置。

SELECT s.score,
@rank_counter := @rank_counter + 1 連續(xù)排名,
IF(@pre_score = s.score, @cur_rank, @cur_rank := @rank_counter) ranking,
@pre_score := s.score
FROM score s, (SELECT @cur_rank :=0, @pre_score := NULL, @rank_counter := 0) r
ORDER BY s.score DESC;

(3)使用case when來實現(xiàn)上面的開窗函數(shù)

SELECT
    s.score,
    @rank_counter := @rank_counter + 1 連續(xù)排名,
    ( CASE WHEN @pre_score = s.score THEN @cur_rank 
                 WHEN @pre_score := s.score THEN @cur_rank := @rank_counter END ) ranking 
FROM
    score s,
    ( SELECT @pre_score := NULL, @cur_rank := 0, @rank_counter := 0 ) ranking 
ORDER BY
    score DESC;
image.png

3锣夹、(1)并列連續(xù)排名dense_rank() over(order by)

select score,
dense_rank() over(order by score desc) ranking
from score;

(2)利用變量@和if來實現(xiàn)上面的開窗函數(shù)

SELECT
    score,
IF
    ( @pre_score = score, @cur_rank, @cur_rank := @cur_rank + 1 ) ranking,
    @pre_score := score 
FROM
    score,
    ( SELECT @pre_score := NULL, @cur_rank := 0 ) ranking 
ORDER BY
    score DESC;

(3)利用case when來實現(xiàn)上面的開窗函數(shù)

SELECT
    score,
    ( CASE WHEN @pre_score = score THEN @cur_rank WHEN @pre_score := score THEN @cur_rank := @cur_rank + 1 END ) ranking 
FROM
    score,
    ( SELECT @pre_score := NULL, @cur_rank := 0 ) ranking 
ORDER BY
    score DESC;
image.png

二页徐、分組的情況下的rank/dense_rank/row_number
1、(1)連續(xù)排名row_number() over(partition by order by)

SELECT
    course_id,
    score,
    row_number ( ) over ( PARTITION BY course_id ORDER BY score DESC ) ranking 
FROM
    score 
ORDER BY
    course_id;

(2)使用變量@和if實現(xiàn)上面的開窗函數(shù)

SELECT
    course_id,
    score,
IF
    ( @pre_course_id = course_id, @cur_rank := @cur_rank + 1, @cur_rank := 1 ) ranking,
    @pre_course_id := course_id 
FROM
    score,
    ( SELECT @pre_course_id := NULL, @cur_rank := 0 ) t 
ORDER BY
    course_id ASC,
    score DESC;
image.png

2银萍、(1)并列跳躍排名rank() over(partition by order by)

SELECT
    course_id,
    score,
    rank ( ) over ( PARTITION BY course_id ORDER BY score DESC ) ranking 
FROM
    score;

(2)利用變量和if來實現(xiàn)上面的開窗函數(shù)

SELECT
        course_id,
        score,
    IF
        ( @pre_course_id = course_id, @rank_count := @rank_count + 1, @rank_count := 1 ) t1, #輔助列变勇,組內(nèi)連續(xù)排名
    IF
        ( @pre_course_id = course_id,
        IF( @pre_score = score, @cur_rank, @cur_rank := @rank_count ),
        @cur_rank := 1 
        ) ranking, 
    @pre_course_id := course_id ,
    @pre_score := score 
        FROM
        score,
        ( SELECT @pre_course_id := NULL, @pre_score := NULL, @cur_rank := 0, @rank_count := 1 ) t2 
    ORDER BY
        course_id,
        score DESC;
image.png

3、(1)并列連續(xù)排名dense_rank() over(partition by order by)

SELECT
    course_id,
    score,
    dense_rank ( ) over ( PARTITION BY course_id ORDER BY score DESC ) ranking 
FROM
    score;

(2)利用變量@和if來實現(xiàn)上面的開窗函數(shù)

SELECT
    course_id,
    score,
IF
    (
    @pre_course_id = course_id,
IF
    ( @pre_score = score, @cur_rank, @cur_rank := @cur_rank + 1 ),
    @cur_rank := 1 
    ) ranking,
    @pre_course_id := course_id,
    @pre_score := score 
FROM
    score,
    ( SELECT @pre_score := NULL, @pre_course_id := NULL, @cur_rank := 0 ) t 
ORDER BY
    course_id,
    score DESC;
image.png

整理自:https://blog.csdn.net/u011726005/article/details/94592866#41__134

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末贴唇,一起剝皮案震驚了整個濱河市搀绣,隨后出現(xiàn)的幾起案子飞袋,更是在濱河造成了極大的恐慌,老刑警劉巖豌熄,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件授嘀,死亡現(xiàn)場離奇詭異,居然都是意外死亡锣险,警方通過查閱死者的電腦和手機蹄皱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來芯肤,“玉大人巷折,你說我怎么就攤上這事⊙伦桑” “怎么了锻拘?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長击蹲。 經(jīng)常有香客問我署拟,道長,這世上最難降的妖魔是什么歌豺? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任推穷,我火速辦了婚禮,結(jié)果婚禮上类咧,老公的妹妹穿的比我還像新娘馒铃。我一直安慰自己,他們只是感情好痕惋,可當(dāng)我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布区宇。 她就那樣靜靜地躺著,像睡著了一般值戳。 火紅的嫁衣襯著肌膚如雪议谷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天堕虹,我揣著相機與錄音柿隙,去河邊找鬼。 笑死鲫凶,一個胖子當(dāng)著我的面吹牛禀崖,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播螟炫,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼波附,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起掸屡,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤封寞,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后仅财,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體狈究,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年盏求,在試婚紗的時候發(fā)現(xiàn)自己被綠了抖锥。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡碎罚,死狀恐怖磅废,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情荆烈,我是刑警寧澤拯勉,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站憔购,受9級特大地震影響宫峦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜玫鸟,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一斗遏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鞋邑,春花似錦、人聲如沸账蓉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽铸本。三九已至肮雨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間箱玷,已是汗流浹背怨规。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留锡足,地道東北人波丰。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像舶得,于是被迫代替她去往敵國和親掰烟。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容