使用外部联接
虽然与内部联接不一样常见,但在多表查询中使用外部联接可以提供业务数据的替代视图。 与内部联接一样,你将表示表之间的逻辑关系。 但是,不仅检索具有匹配属性的行,还检索一个或两个表中存在的所有行,无论另一个表中是否存在匹配项。
以前,你学习了如何使用 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 值才会显示在结果中。
现在,我们来看看以下编写为 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)。员工)并显示 Sales.SalesOrder 中匹配行的 Amount 值。 但是,无论员工是否取得了销售订单,都会返回所有员工。 代替 Amount 值,查询将为没有匹配销售订单的员工返回 NULL。
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 一样,外部联接可以在单个匹配列或多个匹配属性上执行。
- 与 INNER JOIN 不同,在 FROM 子句中列出和连接表的顺序对 OUTER JOIN 很重要,因为它将决定选择 LEFT 还是 RIGHT 进行连接。
- 当存在 OUTER JOIN 时,多表联接会更加复杂。 如果随后将中间结果联接到第三个表,则 OUTER JOIN 的结果中存在 NULL 可能会导致问题。 第二个联接的谓词可能会将包含 NULL 的行筛选掉。
- 要仅显示不存在匹配项的行,请在 OUTER JOIN 谓词之后的 WHERE 子句中添加 NULL 测试。
- FULL OUTER JOIN 很少使用。 它返回两个表之间所有的匹配行,以及第一个表中没有在第二个表中匹配的所有行,还有第二个表中没有在第一个表中匹配的所有行。
- 在没有 ORDER BY 子句的情况下,无法预测行返回的顺序。 无法确定是先返回匹配的行还是不匹配的行。