下列是各表的详情,不想自己建表的同学可以直接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. linq查询不包含某个值的记录_MySQL行(记录)的详细操作

    阅读目录 一 介绍 二 插入数据INSERT 三 更新数据UPDATE 四 删除数据DELETE 五 查询数据SELECT 六 权限管理 一 介绍 MySQL数据操作: DML =========== ...

  3. oracle 指定关联,Oracle巧取指定记录以及巧用外关联查询

    51Testing软件测试网n*ue;R,F%SF5j]"f%Q Oracle巧取指定记录以及巧用外关联查询)L,mOf&ym2g0 9xJ}]-y0作者:010032  51Tes ...

  4. week7 day3 记录相关操作之单表查询

    week7 day3 记录相关操作之单表查询 1.1 单表查询的用法 1.2 关键字的执行优先级(重点) 1.3 简单查询 1.4 WHERE约束 1.5 分组查询GROUP BY 1.6 HAVIN ...

  5. #1.从学生表中查询所有学生的所有信息SELECT * FROM `student`#2.从学生表查询所有学生的学号姓名信息并分别赋予别名SELECT StudentNo AS ‘学号‘, St

    #1.从学生表中查询所有学生的所有信息 SELECT * FROM `student` #2.从学生表查询所有学生的学号姓名信息并分别赋予别名 SELECT StudentNo AS '学号', St ...

  6. mysql查询前5条记录_各个数据库中,查询前n条记录的方法

    SQL查询前10条的方法为: 1.select top X *  from table_name --查询前X条记录,可以改成需要的数字,比如前10条. 2.select top X *  from  ...

  7. Bootstrap4+MySQL前后端综合实训-Day08-AM【多表查询sql语句、关联数据的假删除、自动增长主键的获取、栏目管理“数据编辑”按钮的实现】

    [Bootstrap4前端框架+MySQL数据库]前后端综合实训[10天课程 博客汇总表 详细笔记][附:实训所有代码] 目   录 多表查询sql语句 关联数据的假删除(status状态码/数据可恢 ...

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

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

  9. android连接mysql查询表内记录_Android Room数据库多表查询的使用实例

    前言 在SQLite数据库中,我们可以指定对象之间的关系,因此我们可以将一个或多个对象与一个或多个其他对象绑定.这就是所谓的一对多和多对多的关系. 既然要多表查询,所以表之间就得有关联.这时候我们就得 ...

最新文章

  1. win messenger启动随outlook explorer
  2. C# 引用类型的对象克隆(深拷贝)。
  3. step2 . day5 C语言中的结构体和枚举
  4. c++实现,对象池 object_pool
  5. 图像处理理论(二)——形态学、边缘检测、图像金字塔
  6. 【STL学习】自己动手C++编程实现hash table(散列表)
  7. Bootstrap Well 组件
  8. Linux基础-2文件及目录管理
  9. windows取证之镜像取证仿真步骤
  10. threejs 三面体_three.js几何体对象_三维建模_郭隆邦技术博客
  11. 18048 自由落体
  12. 离线部署GitLab
  13. 理论篇3:深度学习之----Momentum优化器(2)
  14. Install VirtualBox Guest Additions for elementary os
  15. 使用Linux命令删除Android的一些垃圾文件
  16. 计算机科学论文写作5-写硕士论文
  17. 如何使用CC攻击中小型网站?
  18. 解决:浏览器下载的Excel文件显示“文件已损坏,无法打开”
  19. LenNet5-MNIST
  20. 交通咨询系统(最短路径问题)

热门文章

  1. 最新DirectXSDK没有dxtrans.h的解决方法
  2. 评论-ClickTracks 2.0
  3. 联想小新air14显示已连接电源但实际上充不进电
  4. 沪深逐笔、快照推送规则总结
  5. 从柏拉图采花问题说起
  6. PS | 文字自适应箱子物体形状, 利用滤镜消失点给纸箱加文字
  7. dirent C语言获取返回第n个文件的全路径
  8. hbs helper分享
  9. c/c++开发方向如何选择?坚持进阶学习c++还有意义吗?
  10. CVPR 2018 最酷的十篇论文