首页/数据/SQL 速查/RIGHT JOIN 右外连接

RIGHT JOIN 右外连接

保留右表全部行,左表无匹配补 NULL;可读性不如把两表交换后用 LEFT JOIN,团队规范里常要求统一成 LEFT JOIN。

SQL 速查数据更新于 2026-10-13

右外连接在做什么

RIGHT JOIN 是外连接的一种:以右表为基准,右表的每一行都出现在结果里,左表找不到匹配时,左表的列补 NULL。它和把两张表交换位置之后的 LEFT JOIN 完全等价,只是书写顺序不同。实际项目里之所以很少用 RIGHT JOIN,是因为人读 SQL 是按书写顺序从左往右看的,多张表混在一起时很容易判断错哪一侧是保留侧。把连接统一成 LEFT JOIN 链条,能显著降低改错概率。

基本信息

适用平台MySQL 8.0 / PostgreSQL 12 及以上,标准 SQL 通用
保留侧右表的全部行都会出现在结果集里
未匹配处理左表对应列补 NULL,行数不少于右表行数
等价改写交换两张表的书写顺序后改用左连接,语义完全一致
团队惯例多表连接统一用左连接链条,减少判断保留侧的心智负担

典型使用场景

  • 维护历史遗留 SQL:老代码里已经写成右连接,需要读懂保留侧再决定是否改写
  • 以业务单据表为基准补全客户主数据,单据表写在右侧
  • 补全维表:以维度表为基准,统计哪些维度还没有被业务数据引用
  • 双表对齐核对:找出只存在于某一张表里的数据
  • 代码评审时逐层确认每张表是保留侧还是被保留侧

示例与等价改写

示例与等价改写
-- 原始写法:保留 users 全部行,左表 orders 缺失时补空
SELECT u.id, u.name, o.id AS order_id
FROM orders o
RIGHT JOIN users u ON u.id = o.user_id;

-- 等价写法:交换两表顺序改用左连接,可读性更好
SELECT u.id, u.name, o.id AS order_id
FROM users u
LEFT JOIN orders o ON o.user_id = u.id;

-- 更常见的目的:找出还没有下过单的用户
SELECT u.id, u.name
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE o.id IS NULL;   -- 这一条就是「从未匹配成功」的意思

连接类型对照

连接写法保留哪一侧未匹配时怎么补
INNER JOIN只保留两侧都匹配上的行不补,直接丢弃
LEFT JOIN保留左表全部行右表列补 NULL
RIGHT JOIN保留右表全部行左表列补 NULL
FULL OUTER JOIN两侧都保留各自缺失的一侧补 NULL
改写时容易忽略过滤条件的位置:放在 ON 里的条件参与匹配判断,放在 WHERE 里的条件作用在结果集上。把针对被保留侧的条件从 ON 挪到 WHERE,会把外连接悄悄退化成内连接。
判断「某张表里没有匹配数据」的通用手法是外连接后对另一侧的主键列做 IS NULL 判断,这个套路在左右连接上都能用,注意判断的列必须是真正会补空的列。

易错点

  • RIGHT JOIN 混在多表连接中容易搞错保留侧,出现「行数不对但语句不报错」的隐性错误,规范做法是统一改写成 LEFT JOIN
  • 调整连接顺序时左右保留侧会级联变化,改前先在测试库核对改前改后的行数是否一致
  • 把过滤条件从 ON 挪到 WHERE:外连接被压成内连接,本该保留的行消失
  • 用 IS NULL 判断未匹配时选错列:若判断的列在匹配行里也可能为 NULL,结论就失真

数据来源与参考

  • MySQL 8.0 Reference Manual · RIGHT JOIN
  • PostgreSQL Documentation · RIGHT OUTER JOIN
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌