MySQL 並列排名和順序排名查詢

沙漠行者發表於2019-04-17

準備。

建立一張叫scores的表,內容如下。因為測試排名,所以就用最簡單的結構。
id score
1 99
2 80
3 87
4 60
5 80
6 99

需求。

獲取分數排名,要求並列排名。如果兩個分數相同,則兩個分數排名(rank)相同。名次之間不應該有“間隔”。

結果如下。

id score rank
1 99 1
6 99 1
3 87 2
2 80 3
5 80 3
4 60 4

sql語句

select id, score, (select count(distinct(score)) from scores as b where b.score > a.score ) + 1 as rank from scores as a order by rank;
先把結果拿出來,然後再分析怎麼思考這個問題。這裡的查詢關鍵字我都沒有大寫,個人習慣!應該是要大寫的。

分析。

按照上面的需求,我們可以知道我們是要做一個按照分數(score)查詢的一個功能,只不過是要給排序好的結果加上一個我們想要的名次。
我們笨想,我們要想知道某個分數排第幾名,是不是知道有幾個比它大就行了。如果有零個比它大的,那麼它就是第一名,如果只有一個比它大,
那麼它就是第二名。以此類推就好了。
那麼我們來分析上面的sql語句。它就是把socres表分成了倆個一樣的表,a 表,b表。然後通過子查詢去查rank的值。
第一步:select id,score, rank from scores order by rank;我們查詢我們要的資訊,但是我們scores表中沒有rank這個欄位,所以就要分成倆個一
       樣的表,做子查詢,來查rank。
第二步:select id,score,(select count(score) from scores as b where b.score > a.score) + 1 as rank from scores as a order by rank;上面說過了
       如果0個比某分數大,那麼它就是第一名。所以我們要再查詢的個數上加1。結果如下:

MySQL 並列排名和順序排名查詢

我們發現結果不是我們預期的。因為我們還沒有去重。比87大的有倆個都是99,那麼87的rank就是2+1=3,而我們要的排名連續不斷的。所以用distinct
關鍵字去重。
第三步:select id, score, (select count(distinct(score)) from scores as b where b.score > a.score ) + 1 as rank from scores as a order by rank;

MySQL 並列排名和順序排名查詢

順序排名預期結果

MySQL 並列排名和順序排名查詢

順序排名我們就按照score欄位倒序查詢即可,只不過是用msyql的變數去做rank。mysql中的變數是用‘@’跟上變數名稱。@rowNum 
php中我們用$rowNum。mysql中賦值用 := 來賦值。(select @rowNum :=0) r 是給變數@rowNum一個初始值為0。這個很好理解。就是
按照我們要排名的欄位倒序去查詢,再用mysql變數給每一條結果加一個排列序號。

sql語句

select t.id, t.score,@rowNum := @rowNum +1 as rank from (select @rowNum :=0) r, scores as t order by t.score desc ;

結果

MySQL 並列排名和順序排名查詢

相關文章