mysql巧用连表查询各科成绩前三名

下列是各表的详情,不想自己建表的同学可以直接copy code,数据随意。
创建表成绩详情表:
CREATE TABLE score (
id int(10) NOT NULL AUTO_INCREMENT,
subject_id int(10) DEFAULT NULL,
student_id int(10) DEFAULT NULL,
score float DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8;
这里写图片描述
创建学生表:
CREATE TABLE student (
id int(10) NOT NULL AUTO_INCREMENT,
name varchar(10) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
学生表结构
创建科目表:
CREATE TABLE subject (
id int(10) NOT NULL AUTO_INCREMENT,
name varchar(10) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
科目表结构

查询语句:

select a.id,a.subject_id,a.student_id,a.score from score as a left join score as b on a.subject_id=b.subject_id and a.score>=b.score
group by a.subject_id,a.student_id,a.score
having count(a.subject_id)>=4
order by a.subject_id,a.score desc;

分析:先将查询语句分别拆开来一步一步分析
select a.id,a.subject_id,a.student_id,a.score,b.id,b.subject_id,b.student_id,b.score from score as a left join score as b on a.subject_id=b.subject_id; #这里把所有的列都列出来了便于对比
这里把表score的每一条同subject_id的数据都连接起来,如图所示:共18*6=108条数据
left join
现在我们可以再进一步处理上面的数据了。这里我们再加上 a.score<=b.score 这个条件筛选再进行一次筛选。
select a.id,a.subject_id,a.student_id,a.score,b.id,b.subject_id,b.student_id,b.score from score as a left join score as b on a.subject_id=b.subject_id and a.score<=b.score;
有同学可能会问为什么不用a.score<b.score来筛选。如果用a.score<b.score来进行筛选的话,如果数据中某个科目出现大量的并列第一名的话那么第一名就会被过滤掉,以至于得不到结果。如图:
这里写图片描述

接下来就是分组:group by a.subject_id,a.student_id,a.score #按subject_id,student_id,score来进行分组;
select a.id,a.subject_id,a.student_id,a.score,b.id,b.subject_id,b.student_id,b.score,count(a.subject_id) from score as a left join score as b on a.subject_id=b.subject_id and a.score>=b.score
group by a.subject_id,a.student_id,a.score; #添加count(a.subject_id)来进行对比易于理解
这里写图片描述
分组后再进行条件查询:having count(a.subject_id)>=4;
接下来就是排序:order by a.subject_id,a.score desc。
这里写图片描述

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值