Skip to content

SQL Full Join

FULL OUTER JOIN(在某些数据库中也写作 FULL JOIN)关键词用于检索左表(table1)和右表(table2)中的所有行。它结合了 LEFT JOIN 和 RIGHT JOIN 的结果。

如果两个表在连接条件(join condition)上存在匹配,则结果行中会包含来自两个表的列。如果一个表中的行在另一个表中没有匹配的行(基于连接条件),结果集仍然会包含该行,但在没有找到匹配的表的列中会填充 NULL 值。

SELECT column_name(s) FROM table1 FULL OUTER JOIN table2 ON table1.join_column = table2.join_column WHERE condition; — Optional: further filter results

注意:某些数据库系统,例如旧版本的 MySQL,不直接支持 FULL OUTER JOIN。在这种情况下,您可以使用 LEFT JOIN 和 RIGHT JOIN 的 UNION ALL 来达到类似的效果(如果使用 UNION 而非 UNION ALL,并且为右连接部分添加了特定的 WHERE 子句,请小心排除交集以避免重复)。

为了演示,我们将使用经典的 Northwind 示例数据库。假设我们有两个关键表:Customers 和 Orders。

“Customers” 表的简化视图:

客户ID客户名称国家
1Alfreds FutterkisteGermany
2Ana Trujillo Emparedados y heladosMexico
3Antonio Moreno TaqueríaMexico
4Around the HornUK — Example customer without orders
…

“Orders” 表的简化视图:

订单ID客户ID订单日期
1030821996-09-18
10309371996-09-19 — Example order for a customer not in the above snippet
10310771996-09-20
…

以下 SQL 语句选择所有客户和所有订单。如果某个客户没有订单,其订单详细信息将为 NULL。如果某个订单所属的客户不在我们选择的客户列表中(或是一个孤立订单),其客户详细信息将为 NULL。

SELECT c.CustomerName, o.OrderID FROM Customers c FULL OUTER JOIN Orders o ON c.CustomerID = o.CustomerID ORDER BY c.CustomerName;

结果集的一部分可能如下所示:

客户名称订单ID
Alfreds Futterkiste10643 — 假设 Alfreds 有此订单
Alfreds Futterkiste10692 — 也有此订单
Ana Trujillo Emparedados y helados10308
Antonio Moreno Taquería10365
Around the HornNULL — 没有订单的客户
NULL10309 — 客户不在 Customers 表中或未匹配到的订单
…

关键点:FULL OUTER JOIN 确保参与连接的两个表中的每一行都在结果中表示出来,使用 NULL 填充没有匹配项的空白。这对于识别在一个表中存在但在另一个表中没有相应记录的情况非常有用,反之亦然。

  • 在两个数据集之间进行数据核对。
  • 查找孤立记录或相关表中没有相应条目的记录。
  • 生成包含关系双方所有实体的综合报告。