多表连接的基本概念
- 从连接方向上看,有横向连接和纵向连接,其中横向连接又分为左连接、内连接、右连接(MySQL只支持这三种连接方式)
- 左连接和右连接的功能一致,只需要将表的顺序调换,所以常用的是左连接和内连接
- 左连接语句:left join,内连接语句:inner join (inner可以省略)
- 左连接会获取左表的所有记录,右表对应的数据进行拼接,没有对应的数据返回空值
- 内连接获取两表共有的记录,其他的记录不被输出
- 纵向连接分为去重和不去重,去重是union,不去重是 union all
- 在横向连接中,对应关系分为一对一连接、一对多连接、多对多连接,连接字段无重复即为一,连接字段有重复即为多,常用的对应关系是一对多连接
- 在一对多连接中,一表的数据会进行复制,匹配多表的数据
- 如果是多对多连接,左表及右表的数据都会复制,最后导致查询结果出现重复
多表连接演示
有学生表stu,字段分别是学生编号s_id,学生姓名s_name,出生日期s_age,性别s_sex

有成绩表sc,字段分别是学生编号s_id,课程编号c_id,成绩score

有课程表co,字段分别是课程编号c_id,课程名称c_name,教师编号t_id

将学生表和成绩表连接
两表的连接字段是s_id,学生表的s_id不重复,成绩表的s_id有重复,是一对多连接,这时一表的数据会复制。学生表有编号为08的记录,成绩表没有08的记录,如果选择用内连接(两表共有的信息)会导致08的记录不被输出;如果用学生表左连(获取左表所有信息,右表对应数据进行拼接,如果没有返回空值)成绩表,保证信息不丢失。
选择哪种连接方式,要看数据和查询要求,具体情况具体决定。
学生表内连接成绩表,on后面跟连接条件,可以使一个条件也可以是多个条件
select
结果如下,返回18条记录,08号同学的信息没有输出

用学生表左连成绩表
select
结果如下,返回19条记录,08号同学的信息被输出,但对应的成绩信息为null

将学生表、成绩表、课程表三表连接
为了保证信息不丢失,用学生表左连成绩表,再左连课程表,成绩表和课程表的链接字段是c_id。代码很简单,直接添加left join
select
结果如下,返回19条记录

将成绩表与成绩表做横向拼接
因为成绩表的s_id是重复的,是多对多连接,多对多连接两表数据都会复制,导致结果是有重复的
select
结果如下,左表的s_id为01的有3条记录,右表s_id为01的也有三条记录,最后返回3*3=9条01的记录,其他类推,结果为48条

将学生表与学生表纵向拼接
去重用union
- 纵向拼接前后都是查询语句,将查询结果纵向拼接再一起,要保证上下两个表的列数一样,如果不一样会报错,并且以上表的字段名称为查询结果的字段名称
select
不去重用union all
select
查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩
在写字段时,如果是两表共有的字段,要表明字段来自哪个表,否则会报错说字段重复,比如stu.s_id,是来自学生表的学生标号
将学生表和成绩表连接,针对s_id分组
select
结果如下:

查询课程编号为01且课程成绩在80分以上的学生的学号和姓名
select
查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
select
group by语句的用法:https://zhuanlan.zhihu.com/p/106767752
having语句的用法:https://zhuanlan.zhihu.com/p/107495600
子查询的用法:https://zhuanlan.zhihu.com/p/138058160