参考地址:https://blog.csdn.net/weixin_39358657/article/details/89644822
通用模板:
select a.*
from ( select t1.*,(select count(*)+1 from 表 where 分组字段=t1.分组字段 and 排序字段<t1.排序字段) as group_id from 表 t1 ) a where a.group_id<=3 # 假设取前3条
举个栗子:
数据准备:
CREATE TABLE Score( s_id VARCHAR(20) COMMENT '学生编号', c_id VARCHAR(20) COMMENT '课程编号', s_score INT(3) COMMENT '分数', PRIMARY KEY(s_id,c_id) )ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT '成绩表'; -- 成绩表测试数据 insert into Score values('01' , '01' , 80); insert into Score values('01' , '02' , 90); insert into Score values('01' , '03' , 99); insert into Score values('02' , '01' , 70); insert into Score values('02' , '02' , 60); insert into Score values('02' , '03' , 80); insert into Score values('03' , '01' , 80); insert into Score values('03' , '02' , 80);
需求:查询每门功课成绩最好的前两名
需求分析:相当于查询课程为‘01’的前两名,课程为‘02’的排名前两名......
套用模板:
select a.s_id,a.c_id,a.s_score,a.group_id from ( select t1.*,(select count(*)+1 from score where c_id=t1.c_id and s_score>t1.s_score) as group_id from score t1 ) a where a.group_id<=2 ORDER BY c_id asc,group_id asc;
结果:
补充:
此处也可以使用下面的查询语句(前提是课程不多)
SELECT *FROM (SELECT a.s_id,a.c_id,a.s_score, @i:=@i+1 as 排名 FROM score a,(SELECT @i:=0)b WHERE a.c_id='01' ORDER BY a.s_score DESC ) c WHERE 排名 BETWEEN 1 AND 2 UNION SELECT *FROM (SELECT a.s_id,a.c_id,a.s_score, @j:=@j+1 as 排名 FROM score a,(SELECT @j:=0)b WHERE a.c_id='02' ORDER BY a.s_score DESC ) c WHERE 排名 BETWEEN 1 AND 2 UNION SELECT *FROM (SELECT a.s_id,a.c_id,a.s_score, @k:=@k+1 as 排名 FROM score a,(SELECT @k:=0)b WHERE a.c_id='03' ORDER BY a.s_score DESC ) c WHERE 排名 BETWEEN 1 AND 2
上面的查询语句使用了变量@变量名:。
select @i:=@i+1 相当于对每一行进行添加序号;SELECT @i:=0设置初始值为0。