MySQL LEFT JOIN
LEFT JOIN(左连接)操作用于从“左”表(在 FROM 子句中提到的第一个表)中检索所有记录,以及从“右”表(在 LEFT JOIN 之后提到的表)中检索匹配的记录。如果在右表中没有找到匹配项,则结果集中来自右表的列将包含 NULL 值。
当你想确保来自某个特定表(左表)的所有数据都出现在结果集中,即使在另一个相关表(右表)中没有对应的数据时,这种类型的连接至关重要。
1. 理解 LEFT JOIN
LEFT JOIN 的主要目的是保留位于 LEFT JOIN 关键字左侧的表中的所有记录。它基于两个表之间的相关列来组合行。如果左表中的某一行在右表中没有匹配的行,LEFT JOIN 仍然会在结果中包含左表的那一行,但会将通常来自右表的所有列填充为 NULL。
考虑两个表:Customers(客户)和 Orders(订单)。一个客户可以下多个订单,或者一个客户可能还没有下任何订单。如果你想查看所有客户的列表以及他们可能下过的任何订单,LEFT JOIN 就是合适的选择。而 INNER JOIN(如上一节所述)只会显示已经下过订单的客户,排除那些没有下过单的客户。
LEFT JOIN 的基本语法如下:
SELECT
column1,
column2,
...
FROM
TableA AS A
LEFT JOIN
TableB AS B ON A.common_column = B.common_column;在这里,TableA 是“左”表,TableB 是“右”表。来自 TableA 的所有行都将包含在结果中。
1.1 概念示例:部门与员工
想象一个包含两个表的公司数据库:Departments(部门)和 Employees(员工)。每个员工在一个特定的部门工作,但即使目前没有分配任何员工,一个部门也可能存在。
如果你想列出所有部门,并且对于每个部门,列出在其中工作的任何员工,你将使用 LEFT JOIN。Departments 表将是你的“左”表。
SELECT
d.department_name,
e.employee_name
FROM
Departments AS d
LEFT JOIN
Employees AS e ON d.department_id = e.department_id;这个查询将返回 Departments 表中的每一个 department_name。如果一个部门有员工,他们的 employee_name 将出现在部门名称旁边。如果一个部门没有员工,它的 department_name 仍然会出现,但该行对应的 employee_name 列将显示为 NULL。
2. LEFT JOIN 的实际示例
我们将使用 world 数据库表来进行演示。具体来说,让我们考虑 City(城市)和 Country(国家)表。每个城市都属于一个国家,但并非 Country 表中的每个国家在 City 表中都有城市记录(例如,如果我们只存储了主要城市)。
2.1 示例 1:列出所有国家及其首都
假设我们想要列出每个国家及其首都城市。并非 Country 表中的每个国家都在 City 表中具有其首都的对应条目(可能缺失或未指定)。LEFT JOIN 确保所有国家都被列出。
Country 表有一个 Capital 列,用于存储作为首都的城市的 ID。
SELECT
c.Name AS CountryName,
cy.Name AS CapitalCity
FROM
Country AS c
LEFT JOIN
City AS cy ON c.Capital = cy.ID;在这个查询中:
Country是左表(别名c)。所有国家都将被包含。City是右表(别名cy)。- 连接条件
c.Capital = cy.ID通过将Country表的首都ID与 City 表的城市ID匹配,将国家与其首都连接起来。 - 如果一个国家的
Capital列在City表中没有匹配的ID,该国家的cy.Name将显示为NULL,但国家本身仍然会被列出。
2.2 示例 2:查找在 City 表中没有城市的国家
LEFT JOIN 的一个常见用例是查找左表中在右表中没有匹配项的记录。这是通过将 LEFT JOIN 与检查右表某列中 NULL 值的 WHERE 子句结合使用来实现的。
假设我们想找出所有在我们的 City 表中没有记录任何城市的国家。
SELECT
co.Name AS CountryName
FROM
Country AS co
LEFT JOIN
City AS ci ON co.Code = ci.CountryCode
WHERE
ci.ID IS NULL;在这个查询中:
Country是左表 (co)。City是右表 (ci)。- 连接条件尝试将每个国家与其城市链接起来。
WHERE ci.ID IS NULL子句过滤结果,仅包含那些在City表中找不到给定国家匹配项的行。这意味着来自City的ID列将是NULL,表明该国家没有记录城市。
2.3 示例 3:列出产品及其类别(包括未分类产品)
考虑一个电子商务场景。你有 Products(产品)表和 Categories(类别)表。某些产品可能尚未分配类别。
要列出所有产品及其关联类别,包括尚未分配类别的产品:
SELECT
p.product_name,
c.category_name
FROM
Products AS p
LEFT JOIN
Categories AS c ON p.category_id = c.category_id;此查询将返回每个 product_name。如果 product_id 匹配,则显示 category_name。如果某产品的分类 ID 为空或在类别表中找不到匹配项,该产品的 category_name 将为 NULL。
4. 总结
LEFT JOIN 是一个强大的工具,用于组合来自多个表的数据,同时保证左表中的所有记录都包含在结果集中。它在创建综合报表(需要查看所有主要实体以及任何相关的次要数据)或识别缺乏关联表对应条目的孤立记录时特别有用。
掌握 LEFT JOIN 能够实现更灵活、更完整的数据检索,防止在无法保证存在匹配项时使用 INNER JOIN 可能导致的数据丢失。在下一课中,我们将探讨 RIGHT JOIN,它的功能与 LEFT JOIN 对称,确保包含来自右表的所有记录。