外部联接(Outer Join)是所有 SQL 联接类型中最不为人知的。也许是因为与其他联接类型相比,外部联接的需求较少。无论如何,外部联接本身并没有什么奇特的。正如我们将在这篇文章中看到的几个外部联接的示例,应该足以消除你对它们的任何误解和困惑。
本文将首先讲述 Outer Join 语句的语法和用途,然后会有一些示例说明。
OUTER JOIN 语法
当左(表 A)或右(表 B)表记录中存在匹配项时,OUTER JOIN(或 FULL OUTER JOIN)关键字会返回两个联接表的所有记录。下面的 VEN 图描述了潜在的匹配项和 OUTER JOIN 语法:
因此,FULL OUTER JOIN 会从返回两个表中不匹配的行,以及两个表中的匹配行。换句话说,无论两个表的联接字段(Clave)值是否匹配,查询都会返回行。
还是一头雾水?不用担心,我们将在下一节中看看一些示例,就能一清二楚。
OUTER JOIN 的实践
在本教程中,我们将使用广为人知的 Northwind 示例数据库。
以下 SQL 语句选择所有客户和所有订单:
SELECT Customers.CustomerName, Orders.OrderID FROM Customers FULL OUTER JOIN Orders ON Customers.CustomerID=Orders.CustomerID ORDER BY Customers.CustomerName;
由 OUTER JOIN 查询生成的结果集的特征之一是,你可能会在任一联接列中看到 Null 值,因为联接列可能出现在一个表中,但不会出现在另一个表中。在下面的屏幕截图中,我们可以看到Navicat Premium 16中上述查询及其结果:
当然,你不会在两个表列中看到 Null,因为值必须至少出现在一个表中。值得注意的是,在 ContactName 列中出现 Null 是有问题的,因为这意味着订单与现有客户无关。这指出数据库设计存在缺陷,很可能是缺少外键约束。
我们的第二个示例是从项目管理数据库中获取数据,即项目经理和项目。以下是 SQL 语句:
SELECT m.name member, p.title project FROM pm.members m FULL OUTER JOIN pm.projects p ON p.id = m.project_id;
同样,我们可以看到 Null 值(至少一个 Null 值)
在这种情况下,结果表明 Jack Daniel 目前没有项目。这是否构成问题将取决于该组织的具体业务。在任何给定时间,项目经理没有项目或未分配项目可能是完全合理的。
总结
希望今天的文章能够帮助你了解外部联接在查询中的用途和用法。最后一件要注意的事:外部联接可能会产生非常大的结果集,因此要谨慎使用它们,并加入筛选子句(例如 WHERE)以尽量减少返回的行数。