你好,我正在学习SQL(Structured Query Language),以写文章的方式整理和输出所学,这是系列文章第五篇,主题是多表查询。

我在前面讲过了简单查询、分组汇总和复杂查询,它们都是在同一张表中查询数据,当想要查询的数据在多张表中,就得用多表查询了。

多表查询要求表与表之间有关联,否则还不如直接用单表查询,具体的原因我会在后面解释,你先记住这个结论。

表的联结

表与表的关联叫做联结,通过表的列来实现。




多表left join 查询索引 left join多表联合查询_mybatisplus多表关联查询


引用自“猴子数据分析”

从上图可以看出,这四张表是通过相同的列名两两联结起来的,通过这种联结关系就可以从多个表中查询数据了。下面,我们来看看具体的实现过程。

为了后面的演示,我创建了下面四张表。


多表left join 查询索引 left join多表联合查询_三张表关联查询统计_02

student——学生信息表


多表left join 查询索引 left join多表联合查询_leftjoin多表联合查询_03

score——成绩表

多表left join 查询索引 left join多表联合查询_三张表关联查询统计_04

course——课程表

多表left join 查询索引 left join多表联合查询_mybatisplus多表关联查询_05

teacher——教师表

多表查询语法

多表查询常用的语法是这样的:


多表left join 查询索引 left join多表联合查询_多表left join 查询索引_06


看起来很复杂,有点懵哈。别急,现在只是让你有个大概的认识,我会逐项拆开讲清楚的。

首先看第2行中的带有表名的部分:


多表left join 查询索引 left join多表联合查询_leftjoin多表联合查询_07


多表left join 查询索引 left join多表联合查询_mybatisplus多表关联查询_08


这是在给表table_a和表table_b取别名,这样后面就可以直接使用别名,而不需要写很长的表名,使用起来更方便。

再来看第二行的on语句:


多表left join 查询索引 left join多表联合查询_leftjoin多表联合查询_09


on语句的作用是给两张表指定联结条件,即两个表通过哪个列联结。以第一张图“联结关系图”为例,学生表和成绩表通过“学号”这一列联结起来,写成sql语句就是这样的:

on a.学号=b.学号。


多表left join 查询索引 left join多表联合查询_mybatisplus多表关联查询


再看将tablea和table_b合并起来的代码:


多表left join 查询索引 left join多表联合查询_mybatisplus多表关联查询_11


将两表合并在一起的关键字是join,[]内的关键字是可选项,分别给出不同的合并方式。可选项的意思是说你可以根据具体问题决定是否使用以及使用哪一个。

最后看第三行:


多表left join 查询索引 left join多表联合查询_多表left join 查询索引_12


当要在三张及三张以上的表中查询数据,只进行一次合并显然不行,这时就要用到第三行所示的代码了,它会对之前合并后的结果与其后的表进行合并。

下面,我详细说明三种合并方式。

inner join

inner join 的意思是内联结,与集合中的交集类似,就是找到在两张表中起到联结作用的列中都存在的值,将那些共同值所在的行一一匹配起来。下面的图形象的描述了这个过程。


多表left join 查询索引 left join多表联合查询_数据_13

引用自“猴子数据分析”

图中学号这一列中,值'0001'是两表共有的,学生表中学号为0001所在的行就和成绩表中学号为0001所在的两行相匹配。


多表left join 查询索引 left join多表联合查询_mybatisplus多表关联查询_14

引用自“猴子数据分析”

上图中出现了一个新的概念“交叉联结”,所谓交叉联结就是指两张表中的行两两组合形成新行。如果左边的表有1行,右边的表有2行,组合后就会产生新的两行数据;如果左边的表有3行,右边的表有2行,组合后就会产生新的6行数据。


多表left join 查询索引 left join多表联合查询_leftjoin多表联合查询_15


我举个具体的例子。查询所有已经选了课的学生的信息,显示学号、姓名、课程号和成绩。


多表left join 查询索引 left join多表联合查询_mybatisplus多表关联查询_16


“已经选了课”这个条件要求学生的学号要同时在学生表和成绩表中出现,所以用 inner join 合并两张表,在学生表中没有选课的学生“马云”和“王思聪”的信息就不会出现在查询结果中。


多表left join 查询索引 left join多表联合查询_三张表关联查询统计_02


另外,因为现在从两个表中查询数据,为了避免错误和混淆,select语句中列名前面都加了别名。

left join

left join 的意思是左联结,如图所示


多表left join 查询索引 left join多表联合查询_数据_18

引用自“猴子数据分析”

多表left join 查询索引 left join多表联合查询_mybatisplus多表关联查询_19

引用自“猴子数据分析”

left join 与 inner join 的不同之处在于,left join 的结果不仅包含了两表中匹配的行,也包含在左表中但不在右表的行。即 left join 的结果由两部分组成:第一、inner join 的结果;第二、在左表中且与右表没有匹配的行,右表中相应位置的值用空值替代。

举个例子,查询所有学生的选课情况,要求显示学生的学号,姓名,课程号,成绩。


多表left join 查询索引 left join多表联合查询_leftjoin多表联合查询_20


查询结果不仅显示选了课的学生的信息,也显示没有选课的学生的信息。

right join

顾名思义,这是右联结。


多表left join 查询索引 left join多表联合查询_leftjoin多表联合查询_21

引用自“猴子数据分析”

多表left join 查询索引 left join多表联合查询_三张表关联查询统计_22

引用自“猴子数据分析”

与 left join 恰好相反,右联结的结果中包含的是在右表中且与左表没有匹配的行。

举个例子。查询所有课程被选择的情况,显示学号,课程号和课程名称。


多表left join 查询索引 left join多表联合查询_三张表关联查询统计_23


生物这门课没人选。

上面这些例子都是从两张表查询数据,下面我举两个在三个表及更多的表中查询数据的例子。

从三个表中查询。查询所有学生的选课情况及成绩,显示学号,姓名,课程号,课程名称,成绩。


多表left join 查询索引 left join多表联合查询_多表left join 查询索引_24


从四个表中查询。查询所有学生的选课情况、成绩及任课教师信息,显示学号,姓名,课程号,课程名称,成绩,教师号,教师姓名;


多表left join 查询索引 left join多表联合查询_数据_25


如果两个表之间没有关联,会发生什么情况呢?你应该已经得到了,要么结果是空的,要么就是只得到某一个表的数据。

inner join


多表left join 查询索引 left join多表联合查询_多表left join 查询索引_26


left join


多表left join 查询索引 left join多表联合查询_数据_27


right join


多表left join 查询索引 left join多表联合查询_mybatisplus多表关联查询_28


所以说,如果表与表之间没有关联,就不适合用多表查询来查询其中的数据。

最后,我给你做个小结:

1、表与表通过由关联的列联结在一起;

2、多表查询的基本语法是:


多表left join 查询索引 left join多表联合查询_多表left join 查询索引_06