【SQL】联结:几种联结的介绍 - 图1

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

一、SELECT 语句

一个典型的 SQL 查询语句具有如下形式:

from 子句是一个查询求值中需要访问的关系列表。

where 子句是一个作用在 from 子句关系属性上的谓词。

其中 from 这个子句定义的是一个在该子句中列出的关系上的笛卡尔积。可以用如下表述:

【SQL】联结:几种联结的介绍 - 图2

表 2:Address

【SQL】联结:几种联结的介绍 - 图3

测试 FROM 语句,会产生如下的笛卡尔积:

【SQL】联结:几种联结的介绍 - 图4

二、内部联结

内部联结又称为等值联结,将两个表中存在联结关系的字段符合联结关系的那些记录形成记录集的联结。用 INNER JOIN 指定表之间的关系,用 ON 子句指定联结条件。

首先看看不加联结条件的内部联结:

【SQL】联结:几种联结的介绍 - 图5

这个结果和 select * from Name, Address 一样。

再加上联结条件:Name.id = Address.id

【SQL】联结:几种联结的介绍 - 图6

其结果就是显式 id 相等的部分。

这个其实和语句 SELECT WHERE 一样的,来看下面的结果:

【SQL】联结:几种联结的介绍 - 图7

三、自然联结

自然联结其实和内部联结一样,只是不会出现相同的重复列。比如在上边的 INNER JOIN 中,出现了两个 id 列,他们一模一样。

在以前的版本中,有 natural join 来实现自然联结,也就是去除重复的列。在最新版本的 MySQL 中,不在支持 natural join。把这项工作交给了用户。

如果我们想得到不重复的列,可以这样做:

【SQL】联结:几种联结的介绍 - 图8

四、外部联结

外部联结中包含了在相关表中没有关联的行。举个例子,我在 Name 表中再插入一行,这一行在 Address 表中没有对应的 id 记录这个人的地址。

【SQL】联结:几种联结的介绍 - 图9
【SQL】联结:几种联结的介绍 - 图10

如果我们使用内部联结,就不会出现 “Fox” 这个人的信息。

【SQL】联结:几种联结的介绍 - 图11

但是我想显示所有人的信息,不管他们有没有地址。这就可以使用外部联结。

外部联结分为 LEFT OUTER JOIN 和 RIGHT OUTER JOIN。比如我这里使用 LEFT OUTER JOIN:

【SQL】联结:几种联结的介绍 - 图12

上边的语句使用了 LEFT OUTER JOIN。它以左边的表(也就是 Name)作为基准,会选择 Name 中的所有行,如果该行在 Address 表中不存在相应的记录,就会以 null 值(必须要支持 null 值)显示。

同理,RIGHT OUTER JOIN 是以右边的表作为基准。
https://blog.csdn.net/PinkFriday/article/details/79038381

5. 联结表

维护引用完整性:在记录表中的ID出现合法值(即ID也在信息表中的值)
叉联结 有时我们会听到返回称为叉联结(cross join)的笛卡儿积的联结类型。
内联结(等值联结):基于两个表之间的相等测试,只保留了匹配的行
外联结:都会保留未匹配的行,A表联结B表,left join(保留A所有行),right join(保留B所有行), full join(保留A和B的所有行) ,
联结多个表:image.png

  • 创建高级联结
    • 使用表别名:缩短SQL语句,多次使用相同的表
    • 自联结:有时比子查询快的多,应比较子查询和自联结哪种性能更好
    • 自然联结
    • 外部联结
    • 使用带聚集函数的联结 ```sql — 记录表table1,信息表table2 — 下面两句同等结果,第二种是首选 select c_name,g_name,price from table1,table2 where table1.id = table2.id order by table1.name,table2.name; select c_name,g_name,price from table2 inner join table1 on table1.id = table2.id order by table1.name,table2.name;

— 自联结 select id,name from table1 where c_name = (select c_name from table1 where id = ‘dtntr’); select T_a.id,T_a.name from table1 as T_a,table1 as T_b where T_a.c_name = T_b.c_name and T_b.id = ‘dtntr’;

— 内联结 inner join table2 on SELECT * FROM movies M inner join Boxoffice B on M.id=B.Movie_id

``` 内联结 (inner) join on
image.png
左联结 left join on
image.png