SQL联结 - 左外联结、右外联结、全联结

阅读:450
	上节我们讲解到内联结,是把符合ON子句条件的数据输出。本节开始讲解左外联结、右外联结和全联结。

1. 左外联结

左外联结使用LEFT OUTER JOIN,其中OUTER关键字可以省略,联结条件用ON子句。联结语句左边的表我们称为左表,右边的为右表。

左外联结是把左表的所有行输出,若右表中没有对应的记录,相应字段为NULL。

在开始实验之前,我们先对课程表和课程分类表各插入一条数据。插入SQL如下,直接复制到MySQL 客户端执行即可。

INSERT INTO `d_mall`.`t_course`(`id`, `title`, `intro`, `sell_price`, `hot`, `category_id`, `create_time`, `update_time`) VALUES (32, 'Java技术专家教程', 'Java技术专家教程,持续更新中', 100.00, 100, 11, '2020-12-10 14:50:28', '2020-12-10 14:50:33');

INSERT INTO `d_mall`.`t_category`(`id`, `name`) VALUES (12, '读书');

 

我们查询所有的课程,并输出课程分类,用左外联结查询,SQL如下:

SELECT title, name FROM t_course c LEFT JOIN t_category tc ON c.category_
id = tc.id;

输出结果:

+-------------------------------------------------+-----------+
| title                                           | name      |
+-------------------------------------------------+-----------+
| Java教程:核心技术一网打尽                      | 后端      |
| Java面试教程                                    | 后端      |
| redis基础教程                                   | 中间件    |
| 深入理解MySQL底层原理                           | 中间件    |
| kafka教程                                       | 中间件    |
| Spring Cloud基础教程                            | 后端      |
| 架构师教程                                      | 架构      |
| git教程                                         | 后端      |
| 深入剖析Java虚拟机                              | 后端      |
| SQL教程                                         | 中间件    |
| 设计模式:GOF的23种设计模式全剖析               | 后端      |
| HTML教程                                        | 前端      |
| HTML5教程                                       | 前端      |
| CSS教程                                         | 前端      |
| JavaScript教程                                  | 前端      |
| HTTP协议                                        | 前端      |
| Tomcat教程                                      | 中间件    |
| Servlet教程                                     | 后端      |
| Jsp教程                                         | 前端      |
| Ajax教程                                        | 前端      |
| JQuery教程                                      | 前端      |
| Maven教程                                       | 后端      |
| Linux教程                                       | 后端      |
| JDBC教程                                        | 后端      |
| Spring教程                                      | 后端      |
| Spring MVC教程                                  | 后端      |
| Spring boot教程                                 | 后端      |
| MyBatis教程                                     | 后端      |
| ActiveMQ教程                                    | 中间件    |
| ZooKeeper教程                                   | 中间件    |
| dubbo教程                                       | 中间件    |
| Java技术专家教程                                | NULL      |
+-------------------------------------------------+-----------+
32 rows in set (0.00 sec)

我们看到输出结果,左表t_course所有的课程数据都输出了,Java技术专家教程这个课程对应的category_id为11,在右表t_category的id为11的没有数据,所以该列输出为NULL。

 

2. 右外联结

右外联结使用RIGHT OUTER JOIN,其中OUTER关键字可以省略,联结条件用ON子句。

右外联结是把右表的所有行输出,若左表表中没有对应的记录,相应字段为NULL。刚好和左外联结相反。

我们查询所有的课程分类,并输出课程名称,用右外联结查询,SQL如下:

SELECT title, name FROM t_course c RIGHT JOIN t_category tc ON c.category
_id = tc.id;

输出结果:

+-------------------------------------------------+--------------+
| title                                           | name         |
+-------------------------------------------------+--------------+
| Java教程:核心技术一网打尽                      | 后端         |
| Java面试教程                                    | 后端         |
| redis基础教程                                   | 中间件       |
| 深入理解MySQL底层原理                           | 中间件       |
| kafka教程                                       | 中间件       |
| Spring Cloud基础教程                            | 后端         |
| 架构师教程                                      | 架构         |
| git教程                                         | 后端         |
| 深入剖析Java虚拟机                              | 后端         |
| SQL教程                                         | 中间件       |
| 设计模式:GOF的23种设计模式全剖析               | 后端         |
| HTML教程                                        | 前端         |
| HTML5教程                                       | 前端         |
| CSS教程                                         | 前端         |
| JavaScript教程                                  | 前端         |
| HTTP协议                                        | 前端         |
| Tomcat教程                                      | 中间件       |
| Servlet教程                                     | 后端         |
| Jsp教程                                         | 前端         |
| Ajax教程                                        | 前端         |
| JQuery教程                                      | 前端         |
| Maven教程                                       | 后端         |
| Linux教程                                       | 后端         |
| JDBC教程                                        | 后端         |
| Spring教程                                      | 后端         |
| Spring MVC教程                                  | 后端         |
| Spring boot教程                                 | 后端         |
| MyBatis教程                                     | 后端         |
| ActiveMQ教程                                    | 中间件       |
| ZooKeeper教程                                   | 中间件       |
| dubbo教程                                       | 中间件       |
| NULL                                            | 算法         |
| NULL                                            | 后端         |
| NULL                                            | 架构         |
| NULL                                            | 算法         |
| NULL                                            | 中间件       |
| NULL                                            | 程序人生     |
| NULL                                            | 读书         |
+-------------------------------------------------+--------------+
38 rows in set (0.00 sec)

通过输出结果我们看到,右表t_category课程分类表所有行都输出,而左右t_course的课程分类号和右表不对应的行,以NULL输出。

3. 全联结

全联结使用FULL OUTER JOIN,其中OUTER关键字可以省略,联结条件用ON子句。

全联结是左表和右表都输出,不匹配的字段输出为NULL。可惜的MySQL不支持全联结,Oracle是是支持的。没关系,MySQL可以通过UNION子句(下节我们会讲解)输出同样的结果。SQL如下:

SELECT title, name FROM t_course c LEFT JOIN t_category tc ON c.category_id = tc.id
UNION
SELECT title, name FROM t_course c RIGHT JOIN t_category tc ON c.category_id = tc.id;

 

输出结果:

+-------------------------------------------------+--------------+
| title                                           | name         |
+-------------------------------------------------+--------------+
| Java教程:核心技术一网打尽                      | 后端         |
| Java面试教程                                    | 后端         |
| redis基础教程                                   | 中间件       |
| 深入理解MySQL底层原理                           | 中间件       |
| kafka教程                                       | 中间件       |
| Spring Cloud基础教程                            | 后端         |
| 架构师教程                                      | 架构         |
| git教程                                         | 后端         |
| 深入剖析Java虚拟机                              | 后端         |
| SQL教程                                         | 中间件       |
| 设计模式:GOF的23种设计模式全剖析               | 后端         |
| HTML教程                                        | 前端         |
| HTML5教程                                       | 前端         |
| CSS教程                                         | 前端         |
| JavaScript教程                                  | 前端         |
| HTTP协议                                        | 前端         |
| Tomcat教程                                      | 中间件       |
| Servlet教程                                     | 后端         |
| Jsp教程                                         | 前端         |
| Ajax教程                                        | 前端         |
| JQuery教程                                      | 前端         |
| Maven教程                                       | 后端         |
| Linux教程                                       | 后端         |
| JDBC教程                                        | 后端         |
| Spring教程                                      | 后端         |
| Spring MVC教程                                  | 后端         |
| Spring boot教程                                 | 后端         |
| MyBatis教程                                     | 后端         |
| ActiveMQ教程                                    | 中间件       |
| ZooKeeper教程                                   | 中间件       |
| dubbo教程                                       | 中间件       |
| Java技术专家教程                                | NULL         |
| NULL                                            | 算法         |
| NULL                                            | 后端         |
| NULL                                            | 架构         |
| NULL                                            | 中间件       |
| NULL                                            | 程序人生     |
| NULL                                            | 读书         |
+-------------------------------------------------+--------------+
38 rows in set (0.02 sec)

 

通过输出我们可以看出,结果相当于左外联结和右外联结的和。

除此之外,MySQL还有自然联结,通过NATURAL修饰。通过MySQL自己的判断完成连接过程,不需要指定连接条件。MySQL会使用表内的,相同的字段,作为连接条件,在这里我们不做讲解了。

 

总结:

  • 内联结没有左右之分,只输出符合ON子句条件的数据。
  • 外联结分左外联结和右外联结,左外联结是输出所有左表的数据,右表没有对应的行,则该字段输出为NULL,右外联结相反。
  • 全联结相当于左外联结和右外联结的和。

赞赏支持


精彩留言

发表评论