30 右连接与全连接
RIGHT JOIN 是 LEFT JOIN 的镜像:右侧每一行都会保留,即使左侧没有匹配。FULL OUTER JOIN 保留两侧的每一行,未匹配的列用 NULL 填充。实际使用中,LEFT JOIN 比 RIGHT JOIN 常见得多——把“主”表放在前面,再用 LEFT JOIN 引入补充数据,通常更自然。需要同时查看匹配项和两类孤立行时(例如对账报告),FULL JOIN 就很有用。
本章要点
RIGHT JOIN:保留右侧全部内容FULL JOIN:保留两侧全部内容- 为什么
LEFT JOIN通常更易读 - 找出未匹配的行:
WHERE other.id IS NULL - 两侧可能为 NULL 时如何排序
示例
RIGHT JOIN A ON ... 与交换表后的 LEFT JOIN A 完全等价——A LEFT JOIN B ON cond 与 B RIGHT JOIN A ON cond 相同。大多数风格指南建议把 RIGHT JOIN 改写为 LEFT JOIN,这样“主”表会出现在 FROM 子句的前面。
FULL OUTER JOIN 是对称的连接形式:两侧每一行都会出现,未匹配的列为 NULL。第 3 个订单(customer_id = 99)会以 NULL name 出现;Bob 和 Carol 会以 NULL 订单列出现。ORDER BY ... NULLS LAST 会让结果更易读。
经典的反连接模式——“A 中没有在 B 中匹配的行”——使用 LEFT JOIN ... WHERE B.id IS NULL。PostgreSQL 能识别这种写法,通常会把它规划成高效的反连接。
运行示例
运行方式(需要上一课创建的表):
常见陷阱
- 先写
RIGHT JOIN,然后还得在脑子里把列顺序翻过来。交换表的顺序,改用LEFT JOIN,可读性更好。 FULL JOIN的结果两侧都可能有 NULL;如果ORDER BY没有指定NULLS LAST/FIRST,它们可能会散落在结果中,令人困惑。- 使用
WHERE other.id IS NULL处理LEFT JOIN是反连接的惯用写法。NOT EXISTS (...)和NOT IN (...)是替代方案——在含有 NULL 时,NOT EXISTS通常最安全。 - 用
FULL JOIN连接多个表通常不是你想要的结果——类似笛卡尔积的行为会叠加。最好只在简单场景中使用。
对于“显示两个集合的对称差”(只存在于其中一个集合的行),FULL OUTER JOIN ... WHERE a.id IS NULL OR b.id IS NULL 是惯用写法——对账两个数据快照时很方便。
在 FULL JOIN 中加入 WHERE 子句,只显示未匹配的行:WHERE c.id IS NULL OR o.id IS NULL。然后交换表顺序,把上面的 RIGHT JOIN 改写成 LEFT JOIN——自己确认结果相同。
下载
SQL 文件:right-and-full-join.sql · 全部示例文件 · 准备工作