mysql内连接和外连接有什么区别_mysql连接类型说明

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

内连接只返回匹配行,外连接会保留某一方的全部数据

内连接(

INNER JOIN
)本质是“交集”:只有左表和右表都存在满足
ON
条件的记录,才会出现在结果里。外连接(
LEFT JOIN
/
RIGHT JOIN
)则是“保留+补空”:比如
LEFT JOIN
保证左表所有行都出现,右表没匹配上的字段填
NULL

常见错误现象:
SELECT * FROM users INNER JOIN orders ON users.id = orders.user_id
查不到没下过单的用户——这不是 bug,是设计如此
使用场景:要查“有订单的用户详情”用内连接;要查“所有用户及其订单(含无订单者)”必须用左外连接 性能影响:内连接通常更快,因为优化器能更早剪枝;外连接需构造临时结果并填充
NULL
,数据量大时内存和排序开销明显上升

LEFT JOIN 和 RIGHT JOIN 本质可互换,但别写 RIGHT JOIN

RIGHT JOIN
在逻辑上等价于把两张表位置调换后的
LEFT JOIN
,但阅读时需要反向理解,容易出错。MySQL 官方文档和主流代码规范都建议统一用
LEFT JOIN
,靠调整表顺序来表达意图。

错误写法:
SELECT u.name, o.amount FROM users u RIGHT JOIN orders o ON u.id = o.user_id
—— 看到
RIGHT
就得倒着读,费脑还易漏条件
正确做法:把主表放左边,关联表放右边,一律用
LEFT JOIN
,例如
SELECT u.name, o.amount FROM orders o LEFT JOIN users u ON u.id = o.user_id
兼容性注意:某些 ORM 或 BI 工具对
RIGHT JOIN
解析不一致,可能报错或生成低效执行计划

ON 和 WHERE 的位置差异,直接决定 NULL 是否被过滤掉

这是最常踩的坑:

ON
是连接时的匹配规则,
WHERE
是连接完成后的结果过滤。在外连接中,把本该写在
ON
的条件误写进
WHERE
,会导致
LEFT JOIN
变成事实上的内连接。

错误示例:
SELECT u.name, o.status FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE o.status = 'paid'
——
WHERE
会把所有
o.status
NULL
的行(即无订单用户)全干掉
正确写法:若想查“所有用户 + 其已支付的订单”,应把条件移到
ON
SELECT u.name, o.status FROM users u LEFT JOIN orders o ON u.id = o.user_id AND o.status = 'paid'
原理:优化器先按
ON
构建临时结果(含
NULL
),再用
WHERE
扫一遍——此时
NULL = 'paid'
永远不成立,整行就被踢了

MySQL 不支持 FULL OUTER JOIN,但 UNION 能凑合用

当真需要“两边都不丢数据”的全外连接效果时,MySQL 原生不提供

FULL OUTER JOIN
语法,但可用
UNION ALL
拼接两个外连接结果实现等效逻辑。

典型场景:合并两套独立系统中的用户表,要列出所有用户 ID,不管在哪边存在 实操写法:
(SELECT id, 'A' AS src FROM table_a) UNION ALL (SELECT id, 'B' AS src FROM table_b WHERE id NOT IN (SELECT id FROM table_a))
—— 注意用
NOT IN
排除重复,避免笛卡尔积爆炸
风险提示:
UNION ALL
不去重,若两边有同 ID 数据需额外处理;大数据量下性能比原生
FULL JOIN
差不少,建议提前加索引

实际写 SQL 时,先问自己一句:我要的数据,是不是允许某一边为空?如果答案是“是”,那就不能用

INNER JOIN
,也别碰
RIGHT JOIN
,更得盯紧
ON
WHERE
的位置——这三个点卡住,90% 的连接问题就解决了。

相关推荐