SQL JOIN 类型区别定义解析(详解 INNER/LEFT/RIGHT JOIN 该怎么选)

三种连接的核心差异在于”保留哪一侧没有匹配的行”。INNER JOIN 只返回两表都匹配的行;LEFT JOIN 保留左表全部行、右表无匹配补 NULL;RIGHT JOIN 保留右表全部行、左表无匹配补 NULL。选错类型,结果集要么丢数据、要么多出 NULL 行。本文更新于 2026年8月,引用资料截至该时间点。

一、三种连接的本质区别

连接类型 保留的行 不匹配侧的取值 典型场景
INNER JOIN 两表交集(都匹配) 不保留 取有关联的成对记录
LEFT JOIN 左表全部 + 右表匹配 右表列填 NULL 列出左表全部,附带右侧信息
RIGHT JOIN 右表全部 + 左表匹配 左表列填 NULL 列出右表全部,等价于交换顺序的 LEFT JOIN

JOIN 单独书写时默认就是 INNER JOIN,这一行为在所有主流数据库一致(来源:learnsql.com、MySQL 8.0 官方文档)。

二、逐一拆解三种连接

2.1 INNER JOIN:只取交集

INNER JOIN 要求 ON 条件在两表同时成立,才输出该行。MySQL 官方文档定义:INNER JOIN 仅当两表都满足 ON 子句条件时,对应行才出现在结果中(来源:MySQL 8.0 Reference Manual《Using More Than one Table》)。

用 employees 与 departments 两张表说明。employees 含 Alice(部门1)、Bob(部门2)、Charlie(部门1)、David(部门3)、Eve(无部门);departments 含 1=HR、2=Engineering、3=Marketing、4=Finance。INNER JOIN 后结果为 Alice/HR、Bob/Engineering、Charlie/HR、David/Marketing,Eve 因无部门被排除。

2.2 LEFT JOIN:保留左表全部

LEFT JOIN 先按 ON 匹配,再把左表中没匹配到的行也保留下来,右表对应列填 NULL。上例改用 LEFT JOIN,结果在 INNER 的四行之外,多出一行 Eve / NULL——这正是”列出所有员工、没部门就留空”的语义(来源:GeeksforGeeks《MySQL JOIN》、runoob MySQL JOIN)。

2.3 RIGHT JOIN:保留右表全部

RIGHT JOIN 与 LEFT JOIN 对称:保留右表全部,左表无匹配补 NULL。沿用上例,结果在四行匹配之外多出一行 NULL / Finance,表示”Finance 部门暂无员工”。RIGHT JOIN 总能改写成交换表顺序的 LEFT JOIN,得到相同结果(来源:runoob、ylearner SQL Joins Overview)。

三、用 LEFT JOIN 找出”缺失的匹配”

LEFT JOIN 配合 WHERE 右表主键 IS NULL,可筛出”左表存在、右表没有对应行”的记录,即反连接(anti-join)。MySQL 官方文档给出的标准写法:

sql

SELECT left_tbl.*
FROM left_tbl
LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
WHERE right_tbl.id IS NULL;

该语句找出 left_tbl 中所有在 right_tbl 里没有对应 id 的行(来源:MySQL 8.0 Reference Manual《JOIN Clause》)。这是排查”孤儿数据””未下单客户””缺关联记录”的常用手段。

四、为什么 RIGHT JOIN 很少写

MySQL 官方文档明确建议:为保证跨数据库可移植性,优先使用 LEFT JOIN 而非 RIGHT JOIN(来源:MySQL 8.0 Reference Manual《JOIN Clause》)。原因有两点:其一,RIGHT JOIN 与交换表顺序的 LEFT JOIN 完全等价,用 LEFT 一种写法即可覆盖;其二,部分 SQL 实现未提供 RIGHT JOIN(freeCodeCamp 指出 RIGHT JOIN 与 FULL JOIN 在多个 SQL 版本中未被实现)。团队统一用 LEFT JOIN,可读性和一致性更好。

图1(概念示意):用韦恩图理解三种连接——INNER 取两圆重叠部分;LEFT 取左圆全量加重叠;RIGHT 取右圆全量加重叠。该 ASCII/韦恩示意用于建立心智模型,实际结果以 ON 条件为准。

五、引擎如何执行连接

JOIN 的逻辑语义确定后,物理执行方式由查询优化器决定。华为云数据仓库服务(DWS)的官方文档指出,其 SQL 引擎对 JOIN 支持 Nested Loop、Merge Join、Hash Join 三种算法,优化器依据表的统计信息(元组数、字段宽度、distinct 值等)估算每种方式的代价后选定计划(据华为云文档《SQL查询执行流程》,更新于 2026-03-25)。理解连接类型影响的是”语义结果集”,执行算法影响的是”跑得多快”,二者分属不同层面。

六、选型决策清单

按”你要的结果集”倒推连接类型,照此判断:

  1. 只要两表都存在的关联记录 → 用 INNER JOIN。
  2. 要左表全部、右侧有就带、没有留空 → 用 LEFT JOIN。
  3. 要右表全部、左侧有就带、没有留空 → 用 RIGHT JOIN(或直接改写成 LEFT JOIN 换表顺序)。
  4. 想找”左表有、右表没有”的缺失记录 → LEFT JOIN 后加 WHERE 右表主键 IS NULL。
  5. 需要两表并集(含双方缺失侧)→ 用 FULL OUTER JOIN;MySQL 不支持时以 LEFT UNION RIGHT 模拟。
  6. 多表串联时统一用 LEFT/RIGHT 方向,避免混用造成阅读混乱。

常见问题(FAQ)

Q1:JOIN 不加 INNER/LEFT 默认是什么?
A1:默认是 INNER JOIN,所有主流数据库一致,只返回两表匹配的行。

Q2:LEFT JOIN 和 RIGHT JOIN 能互相替换吗?
A2:能。交换两张表顺序,RIGHT JOIN 可改写为 LEFT JOIN,结果相同。

Q3:为什么只匹配的行却出现了 NULL?
A3:用了 LEFT/RIGHT JOIN 且某侧无匹配,该侧列按定义补 NULL,并非数据错误。


参考来源

  • MySQL 8.0 Reference Manual《JOIN Clause》《Using More Than one Table》
  • GeeksforGeeks《MySQL JOIN》《PostgreSQL Joins》
  • runoob《MySQL 连接的使用》
  • learnsql.com《SQL JOINs Explained with Venn Diagrams》
  • freeCodeCamp《SQL Join Types – Inner Join VS Outer Join Example》
  • ylearner.org《SQL Joins Overview》
  • 华为云文档《SQL查询执行流程》
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 qiqicto@qq.com 举报,一经查实,本站将立刻删除。
赞 (0)
其AI的头像其AI普通用户

相关推荐

返回顶部