下列是各表的详情,不想自己建表的同学可以直接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条数据

现在我们可以再进一步处理上面的数据了。这里我们再加上 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是最高分,那么在后面利用group by a.subject_id,a.student_id,a.score分组的时候,此时计算得出的count(a.subject_id)就是最多的(count为总人数),因为其它的分数最多也只是和它一样多,其它的都比它低;同理,如果a.score是最低分,那么count(a.subject_id)是最少的(count最少为1,只有它自己,其余分数都比它高;最多为总人数,这种情况是其它人的分数都和最低分一样多...),其它的分数最差也和它一样多,其它的都比它要高。例如:

100分是最高的,所以几乎其他所有分数都符合100>=其他分数 这个条件,所以100分出现次数最多(count为总人数)

0分,是最低分,几乎其他所有分数都不符合0>=其他分数这个条件,所以0分出现的次数应该是最少的(count最少为1;最多为总人数,此时其他的分数也都是最低分,即大家分数一样低)

有同学可能会问为什么不用a.score > b.score来筛选。如果用a.score > b.score来进行筛选的话,如果数据中某个科目出现大量的并列第一名的话那么第一名就会被过滤掉,以至于得不到结果。如图:

接下来就是分组:group by a.subject_id,a.student_id,a.score #按subject_id,student_id,score来进行分组

(这里使用group by a.subject_id,a.student_id,a.score和使用group by a.subject_id,a.student_id一样的,因为两表左连接之后,不可能出现相同的a.subject_id,a.student_id有多条不同的a.score的记录;因为同一个同学a.student_id,同一个科目a.subject_id,只能有一个分数a.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;

下面来讨论下>=4是什么含义:正常来说,如果每门课程的各个同学的分数都不一样,那么同一门课程中从最高分到最低分的count(a.subject_id) 分别为:6,5,4,3,2,1;取count>=4就是取6,5,4即取count最多的三个,所以取出的数据就是排名前三(count从高到低,取前三,那么就是前三甲的记录):

接下来就是排序:order by a.subject_id,a.score desc。

mysql将多个成绩放在一排_mysql巧用连表查询各科成绩前三名相关推荐

  1. mysql查询各科成绩前三名的记录_mysql巧用连表查询各科成绩前三名

    下列是各表的详情,不想自己建表的同学可以直接copy code,数据随意. 创建表成绩详情表: CREATE TABLE score ( id int(10) NOT NULL AUTO_INCREM ...

  2. MySQL 查询学生的总成绩并进行排名_MySQL查询各科成绩前三名的记录及排名(不考虑成绩并列情况)...

    MySQL查询各科成绩前三名的记录及排名(不考虑成绩并列情况) MySQL查询各科成绩前三名的记录及排名(不考虑成绩并列情况) 我的表结构: 先放代码 -- 查询各科成绩前三名的记录(不考虑成绩并列情 ...

  3. mysql查找各科分数相同的学生_mysql中 查询各科成绩都在80以上的学生的姓名

    最近遇到一个关于mysql的查询的问题,就是在成绩表里查询各科成绩都在80以上(含80分)的学生姓名,在网上找了一个例子,供大家参考学习: 1. 2.也有人在网上用了别外的办法来查找,如下: 使用了分 ...

  4. Mysql查询各科成绩前三名并分别排序

    Mysql查询各科成绩前三名并分别排序 这个问题是之前1个朋友学mysql他们老师布置的作业,一开始我没有做过,而且刚出来做开发很多学过的东西都忘记了. 表结构如下: 一开始我是这样写的: selec ...

  5. mysql查询各科成绩前三名的记录,sql查询各科成绩前三名----详述过程,思路清晰不烧脑...

    使用mysql.hive查询各科成绩前三名 一.建表造数据 建表: create table scores( name varchar(100), subject varchar(100), scor ...

  6. 18、查询各科成绩最高分、最低分和平均分,以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率, -- 优良率,优秀率

    -- 18.查询各科成绩最高分.最低分和平均分:以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率, -- 优良率,优秀率 -- 及格为>=60,中等为:70-80, ...

  7. mysql经典四表查询_mysql经典问题四表查询(教师,学生,成绩,课程表)

    创建数据库 1.创建一个数据库 create database work;web 2.进入数据库work use work;数据库 3.数据库默认编码可能不支持中文,能够在这里设置下 set name ...

  8. mysql统计数学课的及格人数_mysql case when 案例:统计各科成绩各分数段人数所占百分比...

    表信息 成绩表score 课程表course -- 统计各科成绩各分数段人数:课程编号,课程名称,(0-60],(60,70],(70,85],(85,100]所占百分比 然而这么写是不对的~betw ...

  9. mysql 多个select查询_MySQL的select多表查询

    select 语句: select 语句一般用法为: select 字段名 from tb_name where 条件 ; select 查询语句类型一般分为三种: 单表查询,多表查询,子查询 最简单 ...

最新文章

  1. Java集合类解析 ***
  2. QT的QInputDialog类的使用
  3. Syntax error, parameterized types are only available if source level is 1.5
  4. Python3 获取当前路径,当前文件名,当前文件名路径、指定import的文件路径、程序路径
  5. 车辆行人检测数据集_澎思科技行人再识别技术取得突破,刷新三大数据集世界记录...
  6. 如何部署windows服务?
  7. 图说报告|智能技术群的“核聚变”推动智能+时代到来
  8. selenium模拟登录QQ空间
  9. leapftp download,leapftp download如何下载,软件介绍
  10. 银行账户管理(Bank Account Management)
  11. Dubbo之Adaptive注解用法
  12. 转载至:http://blog.csdn.net/antony9118/article/details/51425581
  13. python新手入门(四)
  14. 九爷带你玩转 oracle
  15. 7. JDK拍了拍你:字符串拼接一定记得用MessageFormat#format
  16. DDL、DML和DCL的理解(1、总述)
  17. 【Django】模板
  18. 条件概率、全概率公式和贝叶斯公式
  19. VBA每日一练(4),补充VBA的基础语句知识,基本控制结构,I/O基础
  20. 泽塔云:紧盯用户需求,用差异化竞争和技术创新赢得超融合云计算市场

热门文章

  1. 机器学习——支持向量机SVM之非线性模型(原问题和对偶问题)
  2. 有限元笔记05——板单元(4节点12自由度)和壳单元(4节点24自由度)
  3. SDM For Face Alignment 流程介绍及Matlab代码实现之训练篇
  4. C++中cin、cin.get()、cin.getline()、getline()等函数的用法
  5. 液位系统c语言程序,超声波自动测量物体液位系统的设计
  6. java 任意数平均值_【编程题】通过键盘输入三个任意的数字,计算三个值的平均值,并输出结果。...
  7. azkaban config: nodes:_关于Nordic SDK的sdk.config.h
  8. 51单片机C语言led流水灯及数码管实现秒表
  9. 关于jrebel碰到的一次问题记录
  10. thinkphp5中使用workerman