
本篇文章主题为MySQL多表查询,在实际的业务中,不可能将所有的数据都存到一张表格中,往往会有数张,甚至数十张十张表来支撑整个工作,那我们如何从多个表格中选取需要的数据呢。本节,我们继续对MySQL基础知识深入讲解:如何对多表进行查询?
目录:
- 表的加法
- 表的联结
- case表达式
新增一张名为course_1的表格

表的加法
我们现在有两张课程表分别是课程表course 和 课程表course_1,现在我们想要知道所有的课程都有哪些,我们需要把两张表相加并且不显示重复项,这里我们使用union操作符:
union操作符可以合并多个select语句的结果集。
需要注意的2点:
union内部的select语句必须有相同数量的列;列名顺序必须相同且数据类型必须相似。
一般默认union操作符相加的是不同的值,如果允许重复需要全部显示,可以使用union all操作符:
我们实例来看:
-- 把课程表course 和 course_1 结合,不允许重复
SELECT * FROM course UNION SELECT * FROM course_1;
/*把课程表course 和 course_1 结合,允许重复*/
SELECT * FROM course UNION ALL SELECT * FROM course_1;表的联结
如果想要知道每个学生每门功课的成绩,我们需要把学生表student和成绩表score中获取结果,得到一个更加完整的表,从完整表中查询学生的成绩。这里我们介绍新的关键词——join。
join 用于根据多个表中的列之间的关系,从这些表中查询数据。
在我们的数据表实例中,各表之间都存在关系,是因为有主键key将这些表联系起来:

现在将student表和score表格联系起来:
/*用join把学生表student和成绩表score交叉联结,显示学生成绩*/
SELECT a.学号,a.姓名,b.课程号,b.成绩 FROM student as a JOIN score as b ON a.学号=b.学号;
我们看到,现在每个学生的“学号”“姓名”“课程号”和“成绩”就都显示出来了。
除了上述实例中的join联结,还有其他的联结方式,下面我列出所有的联结方式:
- inner join 内联结:返回两个表可匹配的行;
- left join 左联结:即使左表没有匹配,右表返回所有行;
- right join右联结:即使右表没有匹配,左表返回所有行;
- full join 全联结:只要其中某个表存在匹配九返回所有行;
接下来我们依次实例来说明:
1)inner join 内联结
/*用inner join把学生表student和成绩表score交叉联结,显示学生成绩*/
SELECT a.学号,a.姓名,b.课程号,b.成绩 FROM student as a INNER JOIN score as b ON a.学号=b.学号;

2)left join 左联结
/*用left join把学生表student和成绩表score交叉联结,显示学生成绩*/
SELECT a.学号,a.姓名,b.课程号,b.成绩 FROM student as a LEFT JOIN score as b ON a.学号=b.学号;
3)right join 右联结
/*用right join把学生表student和成绩表score交叉联结,显示学生成绩*/
SELECT a.学号,a.姓名,b.课程号,b.成绩 FROM student as a RIGHT JOIN score as b ON a.学号=b.学号
4)full join 全联结
-- 用full join把学生表student和成绩表score交叉联结,显示学生成绩
SELECT a.学号,a.姓名,b.课程号,b.成绩 FROM student as a FULL JOIN score as b ON a.学号=b.学号;MySQL数据库不支持full join语法,但是可以使用union all语法来代替,但是要记住:union内部的select语句必须有相同数量的列;列名顺序必须相同且数据类型必须相似。
case表达式
先说一下case表达式的作用,就像Excel中的if语句和Python中的if···else···语句,case表达式是SQL中的逻辑判断语句。
举例来看:
① 我们想要查询出每门课程的及格人数和不及格人数:
翻译大白话:
- 定义条件:成绩>=60分及格,成绩<60分不及格;
- 按课程号进行分组,对分组结果的人数按照上一步的逻辑条件计数;
# 查询出每门课程的及格人数和不及格人数
/*
定义条件:成绩>=60分及格,成绩<60分不及格;
按课程号进行分组,对分组结果的人数按照上一步的逻辑条件计数;
*/
SELECT 课程号,
SUM(CASE WHEN 成绩>=60 THEN 1
ELSE 0
END)AS 及格人数,
SUM(CASE WHEN 成绩<60 THEN 1
ELSE 0
END)AS 不及格人数
FROM score
GROUP BY 课程号;

② 我们对各课程的成绩按照[100-85(含)]、[85-70(含)]、[70-60(含)]、[60以下]分段,并统计各分段数人数和课程名
翻译大白话:
- 定义条件:成绩在100-85(含)为[100-85(含)]段,在85-70(含)为[85-70(含)]段,在70-60(含)为[70-60(含)]段,小于60就是[60以下]分段;
- 把成绩表score和课程表course交叉联结(右联结),显示课程号、课程名、和分数段;
- 按课程号、课程名进行分组,对分组结果的人数按照上上述的逻辑条件计数;
-- 对各课程的成绩按照[100-85(含)]、[85-70(含)]、[70-60(含)]、[60以下]分段,并统计各分段数人数和课程名
/*
定义条件:成绩在100-85(含)为[100-85(含)]段,在85-70(含)为[85-70(含)]段,在70-60(含)为[70-60(含)]段,小于60就是[60以下]分段;
把成绩表score和课程表course交叉联结(右联结),显示课程号、课程名、和分数段;
按课程号、课程名进行分组,对分组结果的人数按照上上述的逻辑条件计数;
*/
SELECT a.课程号,b.课程名称,
SUM(CASE WHEN 成绩 BETWEEN 85 AND 100 THEN 1 ELSE 0 END)AS '100-80(含)',
SUM(CASE WHEN 成绩 BETWEEN 70 AND 85 THEN 1 ELSE 0 END)AS '85-70(含)',
SUM(CASE WHEN 成绩 BETWEEN 60 AND 70 THEN 1 ELSE 0 END)AS '70-60(含)',
SUM(CASE WHEN 成绩 <60 THEN 1 ELSE 0 END)AS '60以下'
FROM score AS a RIGHT JOIN course AS b
ON a.课程号=b.课程号
GROUP BY a.课程号,b.课程名称;
本文详细介绍了在MySQL中如何进行多表查询,包括表的加法(使用union和union all操作符)、表的联结(如inner join, left join, right join以及全联结的模拟实现)以及case表达式的使用,通过实例帮助理解这些查询技巧在实际业务中的应用。"
128894137,7783997,UE5多人游戏网络同步详解,"['游戏开发', 'Unreal Engine', '网络编程', '服务器', '客户端']
1万+

被折叠的 条评论
为什么被折叠?



