RIGHT 和 FULL OUTER JOIN 语义
了解各自的适用场景,以及如何将 RIGHT 重写为 LEFT
RIGHT 和 FULL OUTER JOIN 语义 是 CoddyKit 上的免费 SQL Interview Prep 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 SQL Interview Prep 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 SQL Interview Prep 课程共包含 4 节课。
超越 LEFT JOIN
理解 LEFT JOIN 后,面试官会进一步考察它的镜像形式以及两者的合并:RIGHT JOIN 和 FULL OUTER JOIN。
- RIGHT JOIN 会保留右表中的每一行。
- FULL OUTER JOIN 会保留两张表中未匹配的行。
本课会准确解释这两种连接,并展示面试官很喜欢的改写技巧:任何 RIGHT JOIN 都可以改写为 LEFT JOIN。
RIGHT JOIN 的定义
RIGHT JOIN(或 RIGHT OUTER JOIN)会保留右表中的每一行,也就是 JOIN 关键字之后写出的表。未匹配的右表行会出现在结果中,而左表列为 NULL。
它正好是 LEFT JOIN 的镜像形式。LEFT 保留首先写出的表,而 RIGHT 保留第二个写出的表。
SELECT c.name, o.amount
FROM orders o
RIGHT JOIN customers c
ON o.customer_id = c.id;
-- keeps ALL customers, even those
-- with no order (Carol -> amount NULL)再次查看这些表
数据与之前相同。卡罗尔(客户 3)没有订单。这里的所有订单行都引用了现有客户,因此当客户表作为保留侧时,没有订单会成为孤立记录。
-- customers orders
-- 1 | Alice 10 | 1 | 50
-- 2 | Bob 11 | 1 | 75
-- 3 | Carol 12 | 2 | 20将 RIGHT 改写为 LEFT
面试中的要点是:RIGHT JOIN 在实践中很少使用,因为您始终可以交换表的顺序并使用 LEFT JOIN。下面两个查询在逻辑上完全相同。
许多代码风格指南完全禁止 RIGHT JOIN,因为从左到右阅读并始终保留左表更容易理解。
-- RIGHT JOIN
SELECT c.name, o.amount
FROM orders o
RIGHT JOIN customers c ON o.customer_id = c.id;
-- Equivalent LEFT JOIN (preferred)
SELECT c.name, o.amount
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id;FULL OUTER JOIN 的定义
FULL OUTER JOIN 会保留两张表中未匹配的行。您可以把它理解为 LEFT JOIN 和 RIGHT JOIN 的组合:
- 匹配的行对会正常出现。
- 左表中没有匹配项的行:右表列为 NULL。
- 右表中没有匹配项的行:左表列为 NULL。
它可以回答:“显示两侧的全部内容,并将匹配项对齐。”
SELECT c.name, o.id AS order_id
FROM customers c
FULL OUTER JOIN orders o
ON o.customer_id = c.id;FULL OUTER JOIN 发挥作用的场景
FULL OUTER JOIN 是进行对账时的首选:用于比较两组本应匹配但可能存在差异的数据。
假设有一张 orders 表和一张独立的 payments 表。在订单 ID 上使用 FULL OUTER JOIN,可以在一个结果中找出没有付款的订单,以及没有匹配订单的付款记录;缺失的一侧都会通过 NULL 值标记。
SELECT o.id AS order_id, p.id AS payment_id
FROM orders o
FULL OUTER JOIN payments p
ON p.order_id = o.id
WHERE o.id IS NULL OR p.id IS NULL;
-- rows where one side is missingSQL 方言意识
面试官可能会考察可移植性。MySQL 没有 FULL OUTER JOIN 关键字(截至第 8 版)。Postgres、SQL Server 和 Oracle 都支持它。
在 MySQL 中,您可以将 LEFT JOIN 和 RIGHT JOIN 与 UNION 结合起来模拟它(UNION 会移除重复的匹配行)。了解这一差异,能够体现您具备实际项目经验。
-- FULL OUTER JOIN emulated in MySQL
SELECT c.name, o.id FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
UNION
SELECT c.name, o.id FROM customers c
RIGHT JOIN orders o ON o.customer_id = c.id;四种 JOIN 类型一览
请记住这张表。“保留”表示未匹配的行会带着 NULL 继续存在。
- INNER JOIN:仅保留匹配的行,不保留任何未匹配的行。
- LEFT JOIN:保留左侧的所有行。
- RIGHT JOIN:保留右侧的所有行。
- FULL OUTER JOIN:两侧的行都保留。
所有外连接面试题最终都归结为选择要保留哪一侧或哪两侧。
如何在它们之间做选择
选择 JOIN 时,请问自己:“必须保留哪些未匹配的行?”
- 只保留驱动表或主表的行:LEFT JOIN(将主表放在前面)。
- 需要两边的未匹配集合进行对账:FULL OUTER JOIN。
- 只有匹配项重要:INNER JOIN。
您几乎不会主动选择 RIGHT JOIN,而是将它改写为 LEFT JOIN。
对账示例
使用 FULL OUTER JOIN 为每一行标注状态。通过 CASE 检查 NULL 的模式,就能判断哪一侧缺失,这是经典的审计查询。
SELECT
COALESCE(o.id, p.order_id) AS ord,
CASE
WHEN p.id IS NULL THEN 'no payment'
WHEN o.id IS NULL THEN 'orphan payment'
ELSE 'matched'
END AS status
FROM orders o
FULL OUTER JOIN payments p ON p.order_id = o.id;常见误解
候选人经常误以为 FULL OUTER JOIN 会返回未匹配行的笛卡尔积。并不是这样。两侧的未匹配行都会各自准确出现一次,并与 NULL 配对,不会彼此进行乘法组合。
匹配的行仍然遵循普通连接的乘法规则(每个匹配对输出一行),这与任何连接的扇出规则相同。
快速检查
面试官要求您为一个禁止使用 RIGHT JOIN 的团队改写查询。
回顾
RIGHT JOIN 保留右表;FULL OUTER JOIN 保留两侧的行。任何 RIGHT JOIN 都可以通过交换表的顺序改写为 LEFT JOIN,这就是团队偏好 LEFT JOIN 的原因。
- FULL OUTER 适合对账两个数据集。
- MySQL 不支持 FULL OUTER;可以用 LEFT + RIGHT +
UNION模拟。 - 选择连接方式时,要先决定保留哪些未匹配的行。
- 未匹配的行会带着 NULL 出现一次,绝不会形成笛卡尔积。
常见问题解答
「RIGHT 和 FULL OUTER JOIN 语义」课时是免费的吗?
是的 — 「RIGHT 和 FULL OUTER JOIN 语义」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 SQL Interview Prep 课程的其余内容,请升级到 CoddyKit PRO。 SQL Interview Prep 课程共包含 4 节课。
「RIGHT 和 FULL OUTER JOIN 语义」这节课中我会学到什么?
了解各自的适用场景,以及如何将 RIGHT 重写为 LEFT 你通过在浏览器中直接运行的动手代码来练习 SQL Interview Prep,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 SQL Interview Prep 需要有经验吗?
无需任何先前经验。CoddyKit 上的 SQL Interview Prep 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「RIGHT 和 FULL OUTER JOIN 语义」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 SQL Interview Prep 课中编写并运行代码吗?
能。每节 SQL Interview Prep 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- LEFT JOIN 与保留未匹配行
- RIGHT 和 FULL OUTER JOIN 语义
- 查找没有匹配项的行(反连接)
- 外连接中的 WHERE 筛选陷阱