Mysql排序案例和源码解析

mac2026-04-06  6

Mysql排序案例

1、准备数据表和数据
CREATE TABLE `exam` ( `examid` int(11) NOT NULL AUTO_INCREMENT, `studentId` varchar(20) NOT NULL, `subjectId` varchar(20) NOT NULL, `score` int(11) NOT NULL, PRIMARY KEY (`examid`) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 -- 因为主键是自增的所以不需要我们进行维护 INSERT INTO exam VALUES (NULL,'123456',1,60),(NULL,'126556',1,75),(NULL,'12156',2,93),(NULL,'654054',1,86),(NULL,'652314',2,80),(NULL,'645874',2,95),(NULL,'654321',2,93)

通过查询我们可以看到数据表是这样的

SELECT * FROM exam;

2、要求查询出,科目编号为 2 的科目成绩及排名(普通查询即可)
-- 查询一个@rownum增加1,通过:=赋值给新的@rownum SELECT examid,studentid,subjectId,score,@rownum:=@rownum+1 AS rank -- 定义变量初始化 FROM exam a,(SELECT @rownum:=0) b -- 查询科目编号为2 WHERE SubjectId=2 -- 对成绩进行排序 ORDER BY a.score DESC;

注意:代码中“(select @rownum:=0) b”的作用是给变量 rownum 赋值为 0,b一定要带上,不带就报错。 运行效果如下: 观察上图可以发现一个问题,就是第二名和第三名的分数一样,但是排名不同 下面我们就来解决一下分数相同排名也要一样的问题

3、分数相同,名次也要相同
SELECT examid,studentid,subjectId,score, -- 使用case进行比较 CASE -- 当新查询的一条数据的分数和上一条的分数相同时,输出相同名次 WHEN @PREV = a.score THEN @rownum -- 当分数不同是执行下面sql,名次增加一 WHEN @PREV := a.score THEN @rownum := @rownum+1 END AS rank FROM exam a,(SELECT @rownum:=0,@PREV:=NULL) b WHERE SubjectId=2 ORDER BY a.score DESC;

说明:@PREV := a.score既能返回true,又能将a.score赋值与@PREV.

效果图如下: 上面的排名是没有问题的,但是也有一些情况下,要求当出现并列名次时,后面的同学进行跳跃排名

3、实现跳跃排序
SELECT EXAMID,STUDENTID,SUBJECTID,SCORE,RANK FROM (SELECT EXAMID,STUDENTID,SUBJECTID,SCORE, -- if相当于java中的三元运算符,当@PREV=A.SCORE输出@ROWNUM,不相等时输出@INC @ROWNUM:=IF(@PREV=A.SCORE,@ROWNUM,@INC) AS RANK, -- 没执行一次,变量增加1 @INC:=@INC+1, -- 将新的分数赋值于变量@PREV @PREV:=A.SCORE -- 初始化三个参数 FROM EXAM A,(SELECT @ROWNUM:=0,@PREV:=NULL,@INC:=1) B -- 查询科目为2的 WHERE SUBJECTID=2 -- 排序 ORDER BY A.SCORE DESC) TB;

效果图如下: 上述三种排序方法在项目中都可以使用,根据自己的项目需求自行选择即可。

最新回复(0)