三种连接的核心差异在于”保留哪一侧没有匹配的行”。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 官方文档给出的标准写法:
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)。理解连接类型影响的是”语义结果集”,执行算法影响的是”跑得多快”,二者分属不同层面。
六、选型决策清单
按”你要的结果集”倒推连接类型,照此判断:
- 只要两表都存在的关联记录 → 用 INNER JOIN。
- 要左表全部、右侧有就带、没有留空 → 用 LEFT JOIN。
- 要右表全部、左侧有就带、没有留空 → 用 RIGHT JOIN(或直接改写成 LEFT JOIN 换表顺序)。
- 想找”左表有、右表没有”的缺失记录 → LEFT JOIN 后加
WHERE 右表主键 IS NULL。 - 需要两表并集(含双方缺失侧)→ 用 FULL OUTER JOIN;MySQL 不支持时以 LEFT UNION RIGHT 模拟。
- 多表串联时统一用 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查询执行流程》