1. 程式人生 > >mysql @value := 用法

mysql @value := 用法

當前 沒有 技術 src 表示 需要 alias ever 得到

背景

有這麽一張表,記錄名字和分數,現在需要按照成績排名,存在並列名次的情況

技術分享

解決方法

思路:按照score從大到小排序,第一行數據就是第一名,第二行就是第二名......需要判斷當前行的score和上一行的score的大小用來區分是否排名

先看解決代碼:

SELECT name,score
CASE
WHEN @preScore = score THEN @curRank 

WHEN @preScore := score 
THEN @curRank:=@curRank +1

END AS `Rank`
 FROM score,(SELECT
@curRank := 0 AS curRank, @preScore := NULL AS preRank) i WHERE sex=1 ORDER BY score DESC

技術分享

細節說明

@preScore 這種是變量聲明,類似之前的set ,set @a = 1;

:= 賦值,@preScore := 1,表示給@preScore賦值為1;

(SELECT @curRank := 0 AS curRank, @preScore := NULL AS preRank) i 單獨派生出一個表,記得要加別名,不然會包如下的錯誤
Every derived table must have its own alias -- 派生出來的表都要有一個別名

  新增兩列的表,一列是當前排名curRank,一個是上條記錄的score值preScore,賦予默認值,curRank=0,preScore=null;

下面的操作類似linux中的awk操作

1. 按照score倒序排列,即score最大的一行,第一名的一條記錄;

2. 先判斷@preScore是否跟當前查詢出來的score一致,因為默認@preScore為null,那不一致,不執行THEN後面的;

3. 進入到第二個WHEN,THEN中

4. 將當前查詢出來的score=99賦值給@preScore,沒有判斷條件直接進入到THEN,@curRank=0+1,為1

5. 將@curRank 寫為別名Rank=1

6. 第二條記錄掃描

7. 先判斷@preScore(此時為99)跟第二條記錄的score(此時為89)對比,不相等,不執行THEN後面的數據;

8. 將當前查詢出來的score=89賦值給@preScore,沒有判斷條件直接進入到THEN,@curRank=1+1,為2

9. 將@curRank 寫為別名Rank=1

......

掃描完所有的記錄後得到上表

case函數只返回第一個符合條件的值,剩下的case部分將會被自動忽略。

當有score一樣的情況時,@preScore=score時,@curRank並沒有做+1操作,所以就有了並列的情況

mysql @value := 用法