mysql中JOIN操作连接表的几种方式与区别

来源:这里教程网 时间:2026-02-28 20:44:41 作者:

INNER JOIN 只返回匹配的行,不满足条件的数据全被过滤

这是最常用的连接方式,

INNER JOIN
(或简写为
JON
)只保留左表和右表中联结字段值完全相等的记录。一旦某行在任一表中找不到对应匹配,它就不会出现在结果里。

常见错误是误以为它会补空值或保留主表全部数据——其实不会。比如用

users
表关联
orders
表时,没下过单的用户根本不会出现。

等价写法:
JOIN
INNER JOIN
完全相同,MySQL 中无区别
性能上通常最优,因优化器可尽早剪枝 若联结字段有
NULL
,这些行一定不会被包含(
NULL = NULL
FALSE

LEFT JOIN 保留左表全部行,右表无匹配则补 NULL

LEFT JOIN
的关键在于“左表驱动”:无论右表有没有匹配,左表每一行都至少出现一次。没匹配上的右表字段全为
NULL

典型场景是查“所有用户及其最新订单”,即使部分用户没订单也要列出来。但要注意:如果在

WHERE
子句里对右表字段加非空限制(如
WHERE o.status = 'paid'
),就可能把本该保留的左表空匹配行给筛掉——这实际退化成了
INNER JOIN

正确写法:把右表的过滤条件放到
ON
子句里,例如
ON u.id = o.user_id AND o.status = 'paid'
错误写法:
LEFT JOIN ... ON u.id = o.user_id WHERE o.status = 'paid'
→ 丢失无订单用户
索引建议:左表联结字段最好有索引;右表若常用于
ON
后的附加条件,相关字段也应考虑联合索引

RIGHT JOIN 很少用,逻辑上可统一转成 LEFT JOIN

RIGHT JOIN
是以右表为基准保留全部行,左表无匹配则补
NULL
。但它和
LEFT JOIN
本质对称,只是左右调换。几乎所有情况都能通过交换表顺序 + 改用
LEFT JOIN
实现,可读性和维护性更好。

MySQL 手册明确建议避免使用

RIGHT JOIN
,尤其在多表连接中容易绕晕自己。团队代码规范里基本禁止它。

等价转换:
A RIGHT JOIN B ON A.x = B.y
B LEFT JOIN A ON A.x = B.y
执行计划几乎一致,无性能差异 嵌套多个
RIGHT JOIN
时,阅读顺序与执行顺序反直觉,极易出错

FULL OUTER JOIN 在 MySQL 中不存在,需用 UNION 模拟

MySQL 原生不支持

FULL OUTER JOIN
。它的语义是“左右表所有行都保留,各自无匹配的部分用
NULL
填充”。要实现类似效果,必须组合
LEFT JOIN
+
RIGHT JOIN
+
UNION

SELECT u.id, u.name, o.order_id
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
UNION ALL
SELECT u.id, u.name, o.order_id
FROM users u
RIGHT JOIN orders o ON u.id = o.user_id
WHERE u.id IS NULL;

注意这不是严格等价:上面写法会重复出现双方都有匹配的行(即

INNER JOIN
部分)。真正严谨的做法要用
UNION
(去重)并拆成三部分:
LEFT JOIN
(含右表 NULL)、
RIGHT JOIN
(含左表 NULL)、再排除交集。但实际业务中极少需要这么复杂,多数时候用两个
LEFT JOIN
分别查再合并更清晰。

真正容易被忽略的是 NULL 处理:所有

JOIN
类型中,只要字段来自未匹配侧,值就是
NULL
,不是空字符串或 0。做聚合或判断前必须显式用
IS NULL
COALESCE()
处理,否则结果可能不符合预期。

相关推荐