使用外部联接

已完成

虽然不像内部联接一样常见,但在多表查询中使用外部联接可以提供业务数据的替代视图。 与内部联接一样,你将表示表之间的逻辑关系。 但是,你将不仅要检索具有匹配属性的行,而且还要检索一个或两个表中存在的所有行,无论另一个表中是否存在匹配项。

之前,你学习了如何使用 INNER JOIN 查找两个表之间的匹配行。 如你所见,查询处理器通过筛选掉不满足 ON 子句谓词中表述的条件的行,来生成 INNER JOIN 查询的结果。 结果是仅返回在另一个表中具有匹配行的行。 使用 OUTER JOIN,你可以选择显示在表之间具有匹配行的所有行,以及在另一个表中没有匹配项的所有行。 我们来看看一个示例,然后探索该过程。

首先,查看以下使用 INNER JOIN 编写的查询:

SELECT emp.FirstName, ord.Amount
FROM HR.Employee AS emp
INNER JOIN Sales.SalesOrder AS ord
    ON emp.EmployeeID = ord.EmployeeID;

这些行表示“HR.Employee”和“Sales.SalesOrder”之间的匹配。 结果中仅显示两个表中都存在的那些 EmployeeID 值。

A Venn diagram showing the matching members of the Employee and SalesOrder sets

现在,我们来看看以下编写为 LEFT OUTER JOIN 的查询:

SELECT emp.FirstName, ord.Amount
FROM HR.Employee AS emp
LEFT OUTER JOIN Sales.SalesOrder AS ord
    ON emp.EmployeeID = ord.EmployeeID;

本示例使用 LEFT OUTER JOIN 运算符,该运算符指示查询处理器保留左侧表(“HR.Employee”)中的所有行,并显示“Sales.SalesOrder”中匹配行的 Amount 值。 但是,无论员工是否取得了销售订单,都会返回所有员工。 对于没有匹配销售订单的员工,查询将返回 NULL 来代替 Amount 值。

A Venn diagram showing the outer join results of the Employee and SalesOrder sets

OUTER JOIN 语法

外部联接的表示方法是,在 OUTER JOIN 之前使用关键字 LEFT、RIGHT 或 FULL。 关键字的目的在于指示应保留哪个表(在关键字 JOIN 的哪一侧),并显示其所有行(匹配或不匹配)。

使用 LEFT、RIGHT 或 FULL 定义联接时,可以省略 OUTER 关键字,如下所示:

SELECT emp.FirstName, ord.Amount
FROM HR.Employee AS emp
LEFT JOIN Sales.SalesOrder AS ord
    ON emp.EmployeeID = ord.EmployeeID;

但是,像 INNER 关键字一样,编写关于所使用的联接类型的显式代码通常会很有帮助。

使用 OUTER JOIN 编写查询时,请考虑以下准则:

  • 如你所见,表别名不仅是 SELECT 列表的首选,也是 ON 子句的首选。
  • 与 INNER JOIN 一样,OUTER JOIN 可以针对单个匹配列执行,也可以针对多个匹配属性执行。
  • 与 INNER JOIN 不同,在 FROM 子句中列出和连接表的顺序对 OUTER JOIN 很重要,因为它将决定选择 LEFT 还是 RIGHT 进行连接
  • 当存在 OUTER JOIN 时,多表联接会更加复杂。 如果随后将中间结果联接到第三个表,则 OUTER JOIN 的结果中存在 NULL 可能会导致问题。 第二个联接的谓词可能会将包含 NULL 的行筛选掉。
  • 要仅显示不存在匹配项的行,请在 OUTER JOIN 谓词之后的 WHERE 子句中添加 NULL 测试。
  • FULL OUTER JOIN 很少使用。 它返回两个表之间的所有匹配行,第一个表中在第二个表内没有匹配项的所有行,以及第二个表中在第一个表内没有匹配项的所有行。
  • 如果没有 ORDER BY 子句,便无法预测行返回的顺序。 无法知道是先返回匹配的行,还是不匹配的行。