MySQL-多表连接查询

SQL99 的连接查询

SQL99 连接查询的可读性比 SQL92 连接查询更强,查询用的多个数据表显式使用 xxx join 连接,而不是直接依次排列在 from 之后,from 后只需要放一个数据表;连接条件不再放在 where 之后,而是提供了专门的连接条件子句。

SQL99 支持如下几种多表连接查询:

  • 交叉连接。
  • 自然连接。
  • 使用 using 子句的连接。
  • 使用 on 子句的连接。
  • 全外连接或者 左、右外连接。

内连接(inner join)

内连接使用比较运算符进行表与表之间某些列数据的比较操作,并列出这些表中与连接条件相匹配的数据行,组合成新记录。只有满足条件的记录才能出现在结果关系中。

1
2
3
select suppliers.*,fruits.*
from fruits inner join suppliers
on fruits.s_id=suppliers.s_id;

交叉连接(cross join)

交叉连接效果就是 SQL92 中的广义笛卡尔积,所以交叉条件无须任何连接条件:

1
2
3
select s.*,teacher_name
from student_table s
cross join teacher_table t;

自然连接(natural join)

自然连接表面上看起来也无须指定连接条件,但自然连接的确是具有连接条件的,自然连接会以两个表中的同名列作为连接条件;如果两个表中没有同名列,则自然连接与交叉连接效果完全一样:

1
2
3
select s.*,teacher_name
from student_table s
natural join teacher_table t;

using 子句连接

using 子句可以指定一列或多列,用于显式指定两个表中的同名列作为连接条件。假设两个表中有超过一列的同名列,如果使用 natural join,则会把所有的同名列当成连接条件;使用 using 子句,就可显式指定使用哪些同名列作为连接条件:

1
2
3
4
select s.*,teacher_name
from student_table s
join teacher_table t
using(teacher_id);

要注意,如果使用 using 子句来指定连接条件,则两个表中必须有同名列,否则就会报错。

on 子句连接

SQL99 语法的连接条件放在 on 子句中指定,而且每个 on 子句只指定一个连接条件,意味着如果需要进行 N 表连接,就需要有 N-1join…on 对:

1
2
3
4
select s.*,teacher_name
from student_table s
join teacher_table t
on s.java_teacher=t.teacher_id;

左、右 外连接

这三种外连接分别使用 left [outer] joinright [outer] joinfull [outer] join,这三种外连接的连接条件一样通过 on 子句来指定,既可以是等值连接条件,又可以是非等值连接条件。

左连接的结果包括 LEFT OUTER 子句中指定的左表的所有行,而不仅仅是连接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果行中,右表的所有选择列表列均为空值。

以下是 左外连接右外连接的示例,仔细区分二者之间的区别,尤其是如何区分 左表右表

MySQL 不支持全外连接。