MySQL复杂查询:连接查询+取某个类型的最大值

本文链接:https://blog.inchm.cn/default/38.html

需求

假设有一个考试,比如CET(包括CET-4和CET-6),学生可以多次报考刷分。现在某教育单位要从考试结果中把每个学生的CET-6最高分拿出来,然后进行一个排名。

表结构

现在有两个数据表:student 和 exam_result,分别表示学生的基本信息和每次考试结果(包括CET-4和CET-6的结果)。

这里不考虑表结构的优化和完整,只给出必要字段。

student:

字段名 含义
id ID(主键)
name 姓名

exam_result:

字段名 含义
id ID(主键)
cetVersion CET版本或等级(CET-4还是CET-6)
studentId 学生ID
score 成绩

分析

step 1

先尝试把两个表关联起来,LEFT JOIN左连接还记得吗?(连接查询不是关联查询)

SELECT exam_result.studentId, student.name, exam_result.cetVersion, exam_result.score
FROM exam_result
LEFT JOIN student ON (exam_result.studentId=student.id)

step 2

可是我们要的是CET-6的呀,那就在末尾加上 WHERE exam_result.cetVersion=6 吧。千万不要加在FROM后面,语法检查都不给你通过,更不要谈查数据啦。

于是我们就能清晰的看到,只有张三、李四和六神(SixGod)同学参加了六级考试,其中张三还考了两次。

step 3

a

不忙着排序,这个等拿到想要的数据后再来。

先想想怎么“过滤”一下,把每个人多出来的考试记录去掉,只留下最高分的记录。分开来看,就是怎么去重和怎么取最大值的问题。

如果你在搜索引擎上搜索“SQL去重”的话,可能会给出DISTINCT办法,但在:DISTINCT是严格的按照查询字段去重的,相当于你把查询字段都加入了主键,然后以主键唯一作为条件进行查询。比如:SELECT DISTINCT studentId from exam_result,结果理所应当的是去除了重复的studentId;但是只查询一个studentId字段几乎是毫无意义的,还要加上其他字段:SELECT DISTINCT studentId, score from exam_result,你以为会在studentId去重的基础上加上score字段?NO!结果是:(studentId 不唯一) && ( score 不唯一),SQL语句加括号也没用!

b

建议采用GROUP BY进行去重。在【step 2】的基础上,再在末尾添加GROUP BY exam_result.studentId就好了:

SELECT exam_result.studentId, student.name, exam_result.cetVersion, exam_result.score as score
FROM exam_result
LEFT JOIN student ON (exam_result.studentId=student.id)
WHERE exam_result.cetVersion=6
GROUP BY exam_result.studentId

step 4

你应该发现,【step 3】查询出来的结果中,张三的并不是最高成绩。因为默认情况下进行ORDER BY,优先获取的是id在前的记录。

既然我们是要取最高成绩,也就是取score字段的最大值,那么有一个很巧地用法:借用SQL的MAX()方法。

把【step 2】中的exam_result.score换成MAX(exam_result.score) as score,也就是把“查询成绩”换成“查询最好成绩”。

于是我们顺利的拿到了想要的结果:“从考试结果中把每个学生的CET-6最高分拿出来”;还差“然后进行一个排名”,你应该想到用ORDER BY方法了,最终拼拼凑凑弄出了这么个东西,它能“从考试结果中把每个学生的CET-6最高分拿出来,然后进行一个排名”:

SELECT exam_result.studentId, student.name, MAX(exam_result.score) as score
FROM exam_result
LEFT JOIN student ON (exam_result.studentId=student.id)
WHERE exam_result.cetVersion=6
GROUP BY exam_result.studentId
ORDER BY MAX(exam_result.score) DESC

在这个SQl语句中,其实可以简写很多部分,比如把ORDER BY MAX(exam_result.score)简写成ORDER BY MAX(score),毕竟已经在第一行声明了MAX(exam_result.score) as score

结语

在【step 3】【b】开头,我写了“建议采用GROUP BY进行去重”,为什么是“建议”呢?其实DISTINCT也是可以做到我们需要的效果的,但是相对来说比较繁琐,要先在exam_result表内使用UNION合并两个查询结果,然后再去JOIN连接student表。具体的可以Google关键词【distinct multiple fields】或者【distinct multiple columns】。

原文地址:https://www.cnblogs.com/alanabc/p/10167926.html

时间: 2024-08-12 20:50:57

MySQL复杂查询:连接查询+取某个类型的最大值的相关文章

MySql高级查询--连接查询

前言 我们使用SQL查询不能只使用很简单.最基础的SELECT语句查询.如果想从多个表查询比较复杂的信息,就会使用高级查询实现. 常见的高级查询包括多表连接查询.内连接查询.外连接查询与组合查询等,今天我们先来学习最常用.面试也很容易被问到的连接查询. 我们今天以一个简单的学生信息表(学生ID.学生姓名.学生性别)与一个学生成绩表(学生ID.学生成绩.成绩等级)作演示: student_info表: student_score表: 一.内连接(INNER JOIN) 1.等值连接 概述:指使用等

php使用mysql和mysqli连接查询数据

mysql: <?php $code = $_POST['code']; $status = ""; $success = ""; $scookies = ""; try { $dbname="root"; $dbpass="root"; $dbhost="127.0.0.1"; $dbdatabase="mysql"; //生成一个连接 $db_connect

MySql学习 - 查询/子查询/连接查询/联合查询

数据库查询 设定两张数据库表 第一个表格user包含: user_id username age sex 1 Alps1992 22 man 第二个表格toy包含 user_id toyname 1 OnePiece 普通查询: 查询关键字: AS, SUM, DESC, GROUP BY, ORDER BY, AVG, MIN, MAX, COUNT, LIMIT; 关键字查询例子 select * from user as u order by age limit 5; // as 用来做别

Mysql联合,连接查询

一. 联合查询    UNION, INTERSECT, EXCEPT UNION运算符可以将两个或两个以上Select语句的查询结果集合合并成一个结果集合显示,即执行联合查询.UNION的语法格式为:       select_statement    UNION [ALL] selectstatement   [UNION [ALL] selectstatement][…n] 其中selectstatement为待联合的Select查询语句.     ALL选项表示将所有行合并到结果集合中.

MySQL多表查询 三表查询 连接查询的套路

多表查询 * 当我们的一条记录 分散不同的表中时,就需要进行多表查询 例如 一对一 一对多 多对多 1.笛卡尔积查询 意思是将两个表中的所有数据 全部关联在一起   例如 a表 有2条 b表有3条   一共6条   会产生大量的错误数据 需要用添加来过滤select *from 表1,表2,....... where 过滤条件?连接查询内连接查询 inner jon   select *from 表1 join 表2 on 关系过滤条件   两边的数据必须完全匹配成功才显示     select

MySQL中使用连接查询

连接查询: 将多张表(可以大于2张)进行记录的连接(按照某个指定的条件进行数据拼接): 最终结果是: 记录数有可能变化, 字段数一定会增加(至少两张表的合并)! 连接查询的意义: 在用户查看数据的时候,需要显示的数据来自多张表. SQL中将连接查询分成四类:交叉连接,内连接,外连接和自然连接. 在介绍之前先创建两张表作为联系(my_stu,my_class) 1.交叉连接 cross join, 从一张表中循环取出每一条记录, 每条记录都去另外一张表进行匹配: 匹配一定保留(没有条件匹配), 而

MySQL多表连接查询

多表连接查询: create table class( cid int primary key auto_increment, cname varchar(20) )default charset='utf8'; create tablr stu( sid int primary key auto_increment, sname varchar(20). cid int );default charset='utf8'; insert into class(name) values('一班')

MySQL随记 - 连接查询

一.连接分类 1. 内连接 (1)等值连接 (2)非等值连接 (3)自连接 2. 外连接 (1)左外连接 (2)右外连接 (3)全外连接 3. 交叉连接 二.外连接 # 等值连接 # 案例1:查询员工名对应的部门名 SELECT last_name, department_name FROM employees, departments WHERE employees.`department_id` = departments.`department_id`; # 案例2:查询有奖金的员工名.部

数据库数据的查询----连接查询

关系型数据库中允许表和表之间存在关系,这种关系可以把两个甚至多个表的数据联系在一起.利用这种关系,可以查询出某种符合条件的数据,这些数据将是一套符合实际业务逻辑的数据,而数据中这些表和表之间的关系将不存在.换句话说,获取真实世界的原始数据后,根据某种规则吧它们拆分成各种独立的数据,加入想从数据库中再次获取数据,那么需要依靠当初拆分的规则.而这种规则也可以看成表和表之间的联系,要再次实现这种联系,需要用到连接查询.连接分为内连接.外链接和全连接,还有一种叫做自连接,其中最常用的是内连接和外连接.