一、MySQL中沒有排名函數
sql中有排名函數rank()用來排序,但MySQL沒有可排名函數。所以,在mysql中需要自己實現排名。
二、實現方法
假設有張表 t1(id,score), 根據t1表中的score進行分數從大到小進行排名。
此時能夠很容易想到根據score從大到小排序,我們可以寫個 order by score desc 倒序處理。至於排名的序號,就有點難度了。通過引入一個臨時變量(mysql中 @變量名稱的用法),我們可以很容易根據數據記錄的順序得出排名。
三、非並列排名寫法
根據上述的思路,以表t1爲例,可以得出排名sql寫法如下:
SELECT
t1.*,@rank :=@rank + 1 AS rank
FROM
(SELECT @rank := 0) r, t1
ORDER BY t1.score DESC;
結果如下圖,
四、並列排名
上述圖中,可以看到記錄3與記錄4的score是相同的,大部分情況下需要並列排名。並列排名因爲序號相同,那下一名次的是從什麼排名開始呢?
有兩種情況:
- 1、並列排名不佔位 :如上圖中,有2個分數相同,並列第一名,下一名次從第二名開始排名,即名次爲【1,1,2,3】;
- 2、並列排名佔位:上圖中,2個分數相同,在並列第一名後,由於已經有2個人在前面排了名次,所以從第三名開始排,即名次爲【1,1,3,4】
1、並列不佔位
並列排名不佔位sql如下:
SELECT
t1.id,
t1.score,
CASE
WHEN @last_score = t1.score THEN @rank
WHEN @last_score := t1.score THEN @rank :=@rank + 1
END AS rank
FROM
(SELECT @rank := 0 ,@last_score := NULL ) r, t1
ORDER BY
t1.score DESC;
效果如圖:
2、並列佔位
並列排名佔位sql如下:
SELECT id,score,rank FROM (
SELECT
t1.id,
t1.score,
@rank := @rank + 1,
@last_rank:= CASE
WHEN @last_score = t1.score THEN @last_rank
WHEN @last_score := t1.score THEN @rank
END AS rank
FROM
(SELECT @rank := 0 ,@last_rank:=0,@last_score := NULL ) r, t1
ORDER BY
t1.score DESC )t;
效果如圖: