一、SELECT语句
一个典型的SQL查询语句具有如下形式:
-
SELECT A1,A2, ... ,An
-
FROM r1, r2, ... ,rm
-
WHERE P;
select子句列出查询结果中所需要的属性。
from子句是一个查询求值中需要访问的关系列表。
where子句是一个作用在from子句关系属性上的谓词。
其中from这个子句定义的是一个在该子句中列出的关系上的笛卡尔积。可以用如下表述:
-
for each 元组t1
in 关系r1
-
for each 元组t2
in 关系r2
-
...
-
把t1, t2, ..., 连接成单个元组t
-
把t加入到结果关系中
举个例子,我这里有表1:Name
![](https://i-blog.csdnimg.cn/blog_migrate/29e4b344bea07cdf87bc1d16e3237eef.png)
表2:Address
![](https://i-blog.csdnimg.cn/blog_migrate/2c07c91bd61489d00425fcfbdf1332d6.png)
测试FROM语句,会产生如下的笛卡尔积:
![](https://i-blog.csdnimg.cn/blog_migrate/0f966764402e97dd154baa6b3a057a92.png)
二、内部联结
内部联结又称为等值联结,将两个表中存在联结关系的字段符合联结关系的那些记录形成记录集的联结。用INNER JOIN 指定表之间的关系,用ON子句指定联结条件。
首先看看不加联结条件的内部联结:
![](https://i-blog.csdnimg.cn/blog_migrate/525603e5efff69cc7c1b37dae995caaf.png)
这个结果和select * from Name, Address一样。
再加上联结条件:Name.id = Address.id
![](https://i-blog.csdnimg.cn/blog_migrate/1b29401d8369e59c56fe2067a57da665.png)
其结果就是显式id相等的部分。
这个其实和语句SELECT WHERE一样的,来看下面的结果:
![](https://i-blog.csdnimg.cn/blog_migrate/724a2c480e6ab63ba7bb6f93e2990cff.png)
三、自然联结
自然联结其实和内部联结一样,只是不会出现相同的重复列。比如在上边的INNER JOIN中,出现了两个id列,他们一模一样。
在以前的版本中,有natural join 来实现自然联结,也就是去除重复的列。在最新版本的MySQL中,不在支持natural join。把这项工作交给了用户。
如果我们想得到不重复的列,可以这样做:
![](https://i-blog.csdnimg.cn/blog_migrate/e6f3a43d687c58361aa14c1fa0e74f13.png)
四、外部联结
外部联结中包含了在相关表中没有关联的行。举个例子,我在Name表中再插入一行,这一行在Address表中没有对应的id记录这个人的地址。
![](https://i-blog.csdnimg.cn/blog_migrate/4dab1375c09dd2f23767d850ac2caf84.png)
![](https://i-blog.csdnimg.cn/blog_migrate/afc0081410fa38ef814b01b3ba7d8f29.png)
如果我们使用内部联结,就不会出现"Fox"这个人的信息。
![](https://i-blog.csdnimg.cn/blog_migrate/d4b1986c69115ed929edc6c3fe7fe8ba.png)
但是我想显示所有人的信息,不管他们有没有地址。这就可以使用外部联结。
外部联结分为LEFT OUTER JOIN 和RIGHT OUTER JOIN。比如我这里使用LEFT OUTER JOIN:
![](https://i-blog.csdnimg.cn/blog_migrate/84b51aaaa611c561a584a2a79bda20d0.png)
上边的语句使用了LEFT OUTER JOIN。它以左边的表(也就是Name)作为基准,会选择Name中的所有行,如果该行在Address表中不存在相应的记录,就会以null值(必须要支持null值)显示。
同理,RIGHT OUTER JOIN 是以右边的表作为基准。