FULL OUTER JOIN
保留连接两侧的全部记录,并补齐未匹配行。
MySQL 没有原生 FULL OUTER JOIN,本页使用 LEFT JOIN 与 UNION ALL 模拟。
简介
FULL OUTER JOIN 保留两张表中匹配和未匹配的全部记录。PostgreSQL 等数据库支持原生 FULL OUTER JOIN;MySQL 没有原生语法,本页使用两次 LEFT JOIN 配合 UNION ALL 模拟,并在第二段排除已经匹配的行,避免重复。
基础语法
SELECT a.id AS a_id, a.name AS a_name, b.id AS b_id, b.name AS b_name
FROM a
LEFT JOIN b ON a.id = b.id
UNION ALL
SELECT a.id AS a_id, a.name AS a_name, b.id AS b_id, b.name AS b_name
FROM b
LEFT JOIN a ON a.id = b.id
WHERE a.id IS NULL;
示例
FULL OUTER JOIN 示例
连接 a 与 b:保留 id=2 的匹配行,同时保留只出现在 a 或 b 中的未匹配行。
示例数据表
表名:
a| id | name |
|---|---|
| 1 | A1 |
| 2 | A2 |
表名:
b| id | name |
|---|---|
| 2 | B2 |
| 3 | B3 |
运行结果
| a_id | a_name | b_id | b_name |
|---|---|---|---|
| 1 | A1 | NULL | NULL |
| 2 | A2 | 2 | B2 |
| NULL | NULL | 3 | B3 |
常见问题
MySQL 能直接写 FULL OUTER JOIN 吗?
不能。MySQL 通常用两个方向的 LEFT JOIN 配合 UNION ALL 模拟。
为什么第二段查询要排除已匹配行?
第一段已经返回匹配行;第二段只补右表未匹配行,才能避免重复。
为什么模拟写法使用 UNION ALL?
排除已匹配行后两部分不会重复,UNION ALL 不需要额外去重,也不会误删业务上的重复记录。
标签
这篇内容是否清楚?
感谢反馈,我们会把它用于后续内容复核。