首页/数据/数据库速查/LEFT / RIGHT JOIN 外连接
SQL 语法52 条

LEFT / RIGHT JOIN 外连接

保留一侧全部行,另一侧无匹配补 NULL;判断是否存在匹配时要在 WHERE 里排除 NULL 或改用 NOT EXISTS。

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

外连接是什么

LEFT JOIN 与 RIGHT JOIN 属于外连接:保留一侧的全部行,另一侧没有匹配时补 NULL。左连接保留左表全集,右连接保留右表全集,工程上一般统一改写成左连接,保证阅读方向一致。它最容易用错的地方是过滤条件的位置——条件写在 ON 里表示匹配时的附加限制,写在 WHERE 里表示对结果集过滤,对右表列加非空条件会把左连接悄悄退化成内连接。

基本信息

用途保留单侧全集,另一侧可为空
语法A LEFT JOIN B ON 连接条件
方向LEFT 保留左表全部行,RIGHT 保留右表全部行
NULL 补位无匹配时另一侧所有列为 NULL
条件位置ON 影响匹配过程,WHERE 影响最终结果
常见替代NOT EXISTS 表达寻找缺失关联,语义比 NOT IN 更安全

典型使用场景

  • 查哪些用户一单都没有:用户表左连接订单表,右表主键为空
  • 统计每用户订单数并包含零单用户:对右表列计数而不是计数全部行
  • 主记录补可选的附属信息(备注、标签),缺失时不能丢掉主记录
  • 数据质量核查:左连接找出明细表里没有主表记录的孤儿行
  • 报表需要完整维度:日期维表左连接事实表,无数据的日期补零
  • 迁移前后比对:用外连接找出只在一侧存在的记录

左连接找无订单用户

左连接找无订单用户
SELECT u.id, u.name   # 只取左表列,避免右表整列空值干扰阅读
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE o.id IS NULL;   # 右表主键为空即表示没有匹配上

统计每用户订单数含零单

统计每用户订单数含零单
SELECT u.id, COUNT(o.id) AS cnt   # 计右表列,无匹配时结果为 0
FROM users u
LEFT JOIN orders o
  ON o.user_id = u.id AND o.status = 'paid'   # 过滤写在 ON 里,零单用户才不会被剔除
GROUP BY u.id
ORDER BY cnt DESC;   # 按单量倒序看活跃度

ON 与 WHERE 的语义差别

写法结果适用说明
ON o.status='paid'右表只保留已支付行,左表行全部保留统计含零单用户限制匹配范围的标准位置
WHERE o.status='paid'未匹配与未支付的行都被过滤多半是写错了等价于内连接,左表空值行全部消失
WHERE o.id IS NULL只保留没有匹配的左表行找缺失关联最常用的缺口排查写法
ON 里写左表条件不减少左表行,只影响是否匹配不推荐左表条件放 WHERE 更直观
COUNT(*)无匹配行也被算成一条极易出错统计数量会整体虚高
COUNT(o.id)无匹配计为 0统计含零单外连接统计的正确写法
左连接后在 WHERE 里对右表列加非空条件会把外连接退化成内连接,零单用户凭空消失;需要限制右表匹配范围时,把条件写在 ON 里。
计数全部行与计数右表列在外连接下结果不同:前者把补 NULL 的行也算进去,后者跳过空值得到 0,统计含零单用户时只能用后者。
右连接与左连接语义对称,但多表混用时阅读成本高,工程上通常重排表的顺序改成左连接,让整条语句的连接方向保持一致。

外连接检查清单

  • 先确认要保留哪一侧的全部行,表的书写顺序与连接方向必须对应
  • 右表的匹配限制写 ON,结果集过滤写 WHERE,两者不能混用
  • 统计总量与统计含零值用的是不同写法,先明确业务要哪个口径
  • 找缺失关联用右表主键判空,比判断其他业务列更可靠
  • 外连接链条里夹了内连接会截断结果,每段都要验证行数
  • 补空值的结果交给应用前先定义空值语义,避免被当成零值
外连接把右表条件写错位置时不会报错,结果也不为空,只是少了一批行;这类错误很难靠肉眼发现,建议用同样的条件分别做统计计数再比对。

易错点

  • 把右表条件写到 WHERE 里:左连接退化为内连接,零单用户凭空消失,统计口径错了还不容易发现
  • 用计数全部行统计外连接结果:无匹配行也被算作一条,数量整体虚高,应统计右表列
  • 用 NOT IN 替代左连接找缺失:子查询结果里含 NULL 时一行都匹配不上,NOT EXISTS 更可靠
  • 多表连续外连接时方向混乱:链条中间夹一个内连接会把前面的外连接结果过滤掉,越长越要逐段验证行数
  • 外连接后直接返回明细:补 NULL 的列被下游当作空字符串或零值处理,业务判断出错,需先明确空值语义

数据来源与参考

  • MySQL 8.0 Reference Manual: JOIN Clause

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌