在本教程中,我们将介绍另一种称为SQL LEFT JOIN的连接,它用于从多个表中检索数据。
1. SQL LEFT JOIN子句简介
在上一个教程中我们知道,如果两个表中至少有一行与连接条件匹配,则返回行记录的内联接。 内连接子句消除了与另一个表的行不匹配的行。
但是,左连接将返回左表中的所有行,而不管右表中是否存在匹配的行。
假设有两个表A和B。表A有四行:1,2,3和4。表B还有四行:3,4,5,6。
当将表A与表B连接时,表A中的所有行(左表)都包含在结果集中,而不管无论表B中是否存在匹配的行。

在SQL中,使用以下语法将表A与表B连接起来。
SELECT
A.n
FROM
A
LEFT JOIN B ON B.n = A.n;
LEFT JOIN子句出现在FROM子句之后。 ON关键字后面的条件称为连接条件B.n = A.n。
2. SQL LEFT JOIN示例
2.1. SQL LEFT JOIN两个表的例子
我们来看看以下两个表:countries和locations表的结构和关系。
每个地点属于一个且仅一个国家/地区,而每个国家/地区可以具有零个或多个地点。countries和locations表之间的关系是一对多的。
locations表中的country_id列是链接到countries表中country_id列的外键。
要查询美国,英国和中国的国家/地区名称,请使用以下语句。
···
SELECT
country_id,
country_name
FROM
countries
WHERE
country_id IN ('US', 'UK', 'CN');
执行上面查询语句,得到以下结果 -
+------------+--------------+
| country_id | country_name |
+------------+--------------+
| CN | 中国 |
| UK | 英国 |
| US | 美国 |
+------------+--------------+
3 rows in set
以下查询检索位于美国,英国和中国的地点:
SELECT
country_id,
street_address,
city
FROM
locations
WHERE
country_id IN ('US', 'UK', 'CN');
执行上面查询语句,得到以下结果 -
+------------+------------------------------------------+---------------------+
| country_id | street_address | city |
+------------+------------------------------------------+---------------------+
| US | 2014 Jabberwocky Rd | Southlake |
| US | 2011 Interiors Blvd | South San Francisco |
| US | 2004 Charade Rd | Seattle |
| UK | 8204 Arthur St | London |
| UK | Magdalen Centre, The Oxford Science Park | Oxford |
+------------+------------------------------------------+---------------------+
5 rows in set
现在,使用LEFT JOIN子句将countries表与locations表连接为以下查询:
SELECT
c.country_name, c.country_id, l.country_id, l.street_address, l.city
FROM
countries c
LEFT JOIN locations l ON l.country_id = c.country_id
WHERE
c.country_id IN ('US', 'UK', 'CN')
执行上面查询语句,得到以下结果 -

应用WHERE子句中的条件,指示仅检索来自:US,UK和China行的数据。
因为使用LEFT JOIN子句,所以满足countries表的WHERE子句中的条件的所有行都包含在结果集中。
对于countries表中的每一行,LEFT JOIN子句在locations表中查找匹配的行。如果找到至少一个匹配行,则数据库引擎将两个表中匹配行的列中的数据组合在一起。
如果没有找到匹配的行,例如,使用country_id的值是:CN,则countries表中的行包含在结果集中,而locations表中的行用NULL值填充。
由于右表中的非匹配行使用NULL值填充,因此可以将LEFT JOIN子句应用于表之间的未匹配行。
例如,要查找locations表中没有任何地点的国家/地区,请使用以下查询:
SELECT
country_name
FROM
countries c
LEFT JOIN locations l ON l.country_id = c.country_id
WHERE
l.location_id IS NULL
ORDER BY
country_name;
执行以下查询语句,得到以下结果 -
+--------------+
| country_name |
+--------------+
| 中国 |
| 丹麦 |
| 以色列 |
| 印度 |
| 埃及 |
| 墨西哥 |
| 尼日利亚 |
.....
| 荷兰 |
| 赞比亚 |
| 阿根廷 |
| 香港 |
+--------------+
21 rows in set
2.2. SQL LEFT JOIN 3个表的示例
请参阅下表:regions, countries和locations的结构和关系。

一个地区可能有零个或多个国家,而每个国家都位于一个地区。 countries和regions表之间的关系是一对多的。 countries表中的region_id列是国家和地区表之间的链接。
以下语句演示了如何连接3个表:regions, countries和locations:

通过上面的学习,现在您应该很好地理解SQL LEFT JOIN子句的工作原理,并知道如何应用LEFT JOIN子句来查询来自多个表的数据。
