Sql排名和分組排名


在很多時候,都有排名這個功能,比如排行榜,並且還需要分頁的功能,一般可以再select的時候按照某一字段 oorder by XX desc,這樣limit 查找就可以得到排名信息,但是有時候是需要多表連接,或者是有一個隨機查看,在頁面上並不是按照排名升降序。這個時候就需要用SQL來實現排名。

先准備測試數據:

TableCREATE TABLE `test` (

  `Score` int(255) NOT NULL,

  `Name` varchar(255) NOT NULL,

  `Type` varchar(255) NOT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

-- ----------------------------

-- Records of test

-- ----------------------------

INSERT INTO `test` VALUES ('79', '張三', '數學');

INSERT INTO `test` VALUES ('69', '張三', '語文');

INSERT INTO `test` VALUES ('57', '張三', '英語');

INSERT INTO `test` VALUES ('81', '李四', '數學');

INSERT INTO `test` VALUES ('45', '李四', '語文');

INSERT INTO `test` VALUES ('84', '李四', '英語');

INSERT INTO `test` VALUES ('15', '王五', '數學');

INSERT INTO `test` VALUES ('47', '王五', '語文');

 

如果要查詢數學科目的排名,可以用以下sql語句:

select a.*,@a := @a+1 as rank  from test a,(select @a:=0) b where type='

數學 ' order by a.score desc;

 

結果如下:

也就是使用a變量,按照order by的順序遞增。這個很好理解,但是如果有分組排序的需求呢?

 

例如在Test表中,要用一條sql查出數學、語文、英語三個科目各自的排名呢?

 

首先可以想到方法還是類似查詢單科排名,先將所有記錄按照科目、得分排序,Order by Type,Score。然后自定義變量遞增,但是關鍵就在於需要判斷科目的記錄有多少條,也即自定義變量歸零重新遞增的臨界點。

 

簡單排名使用一個變量a,那么在分組排序中可以考慮使用兩個變量,a、b

先執行如下sql

select a.* from test a order by type,score;

 

 

現在加上排名,先使用一個變量看得到什么效果:

select a.*,(@a := @a + 1) as rank from test a,(select @a := 0) b order by

 type,score;

 

 

現在排名並沒有按照科目的不同重新計算,我們只要解決排名何時歸0,就可以得到分組排序的結果了。

再加一個中間變量nowType試試?讓這個中間變量nowType等於Type(科目),只要下一條記錄與這個中間變量nowType相等,rank就加1,不相等的話,rank就歸零,來看下這條SQL:

select a.*,@lastType := @nowType,@ nowType:= a.type,if(@lastType = @nowType,@rank

:= @rank + 1,@rank := 0) as rank from test a,(select @a := 0,@ nowType:= 0,@rank :=

0)      b order by type,score;

 

 

現在看來是不是比較簡單了,lastType用於記錄上一條記錄的Type,nowType是當前記錄的Type,只要nowType=lastType,就說明是同一科目,rank加+,反之,rank歸零。

 

但是我們看到同樣是將rank初始化為0,為什么上面是從1開始,而這次是從0開始呢?再分析下sql,在第一條記錄的時候,lastType=0.而nowType=數學,肯定不相等,所以輸出0,rank從0開始,只要將rank初始化為1就好了。

 

 select a.*,@lastType := @temp,@temp := a.type,if(@lastType = @temp,@rank

:= @rank + 1,@rank := 1) as rank from test a,(select @a := 0,@temp := 0,@rank :=

0)      b order by type,score;  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM