Skip to content

SQL Left Join

LEFT JOIN 子句(也写作 LEFT OUTER JOIN)用于根据两个表之间的相关列合并(combine)行。它返回左表(table1)中的所有行以及右表(table2)中匹配的行。

如果左表中的行没有匹配项,结果仍将包含该行,但右表中对应列的值将为 NULL。

SELECT table1.column1, table1.column2, table2.column1, … FROM table1 LEFT JOIN table2 ON table1.common_column = table2.common_column;

在大多数 SQL 数据库系统(例如 MySQL、PostgreSQL、SQL Server、Oracle)中,LEFT OUTER JOIN 中的 OUTER 关键字是可选的,通常为了简洁而被省略。

从概念上讲,LEFT JOIN 的工作方式如下:

Section titled “从概念上讲,LEFT JOIN 的工作方式如下:”
  1. 它从 table1(在 LEFT JOIN 之前指定的“左”表)的所有行开始。

  2. 对于 table1 中的每一行,它尝试根据 ON 子句中指定的条件在 table2(“右”表)中查找匹配的行。

  3. 如果在 table2 中找到匹配的行,这些行的列将与 table1 中的行合并。

  4. 如果在 table2 中未找到与 table1 中某行匹配的行,则结果仍将包含该 table1 中的行,但从 table2 中选择的列将包含 NULL 值。

对于此示例,我们将使用两个概念表:

  • Customers:包含客户信息,例如 CustomerID(主键)和 CustomerName 列。

  • Orders:包含订单信息,例如 OrderID(主键)、CustomerID(引用 Customers 的外键)和 OrderDate 列。

我们希望列出所有客户以及他们可能下过的任何订单。

以下 SQL 语句将选择所有客户并列出他们对应的订单。如果客户没有订单,他们仍然会被列出,但与订单相关的字段将为 NULL。

SELECT C.CustomerName, O.OrderID, O.OrderDate
FROM Customers C
LEFT JOIN Orders O ON C.CustomerID = O.CustomerID
ORDER BY C.CustomerName, O.OrderDate;

结果的关键点:

  • Customers 表中的所有客户至少会被包含一次。

  • 如果客户下过多个订单,他们将在结果中出现多次,每个订单出现一次。

  • 如果客户没有下过任何订单,其 CustomerName 将被列出,但该行的 O.OrderID 和 O.OrderDate 将为 NULL。

LEFT JOIN 在需要检索某个主要实体(例如所有客户、所有产品)的所有记录,然后选择性地显示另一表中的相关信息时非常有用,即使该相关信息并非存在于主要实体中的每条记录上。

例如,查找从未下过订单的客户:

SELECT C.CustomerName
FROM Customers C
LEFT JOIN Orders O ON C.CustomerID = O.CustomerID
WHERE O.OrderID IS NULL;