mysql @value := 用法
背景
有這麽一張表,記錄名字和分數,現在需要按照成績排名,存在並列名次的情況
解決方法
思路:按照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 := 用法