核心选择口诀
要交集、两边都必须有 → INNER JOIN(内连接) 左边数据一条都不能丢,右边可有可无 → LEFT JOIN(左连接)【最常用】 右边数据一条都不能丢,左边可有可无 → RIGHT JOIN(右连接)【尽量少用】
开发通用建议:优先左连接,能用左连接就不用右连接,调换表顺序就可以替代右连接,阅读更顺畅。
下面分场景、判断步骤、案例、避坑点来讲。
一、先给判断流程(写 SQL 前先问自己 3 个问题)
这条查询的主体数据是谁?哪些记录是必须全部出现在结果里的?
主体必须全部保留 → 用外连接,主体放左边 →
LEFT JOIN
主体记录必须存在,关联数据也必须存在,缺一不可?
两边都要有匹配数据才需要这条结果 →
INNER JOIN
只有右边表是主体,左边可以没有?
等价于调换表顺序改成
LEFT JOIN,不推荐直接写RIGHT JOIN
二、分类型场景详解 + 业务例子
1. INNER JOIN 内连接:求交集
✅ 适用场景:两边的数据都必须匹配成功,这条记录才有意义
只要任意一边找不到匹配,直接丢弃这条数据
业务例子:查询有订单的用户
用户表 user、订单表 order
需求:只要下过单的用户,没有订单的用户不要;不存在用户的脏订单也不要
SELECT u.name, o.order_no
FROM user u
INNER JOIN `order` o ON u.id = o.user_id;
❌ 不适合:需要展示全部用户(包括没下单的)
2. LEFT JOIN 左连接(最高频)
✅ 适用场景:左表是主表,左表所有记录都要保留,关联表数据有就展示、没有就 NULL
业务例子:查询所有用户以及他们的订单(没下单的用户也要显示出来) 主表是用户,用户不能丢,订单可选
SELECT u.name, o.order_no
FROM user u
LEFT JOIN `order` o ON u.id = o.user_id;
⚠️ 重要坑:WHERE 条件里对右连接表字段加
=xxx,会把左连接退化成内连接! 错误示范:-- 错!o.status = 1 会过滤掉 o 为 null 的行,等价内连接 SELECT u.name, o.order_no FROM user u LEFT JOIN `order` o ON u.id = o.user_id WHERE o.status = 1;正确写法:条件放 ON 后面
SELECT u.name, o.order_no FROM user u LEFT JOIN `order` o ON u.id = o.user_id AND o.status = 1;
3. RIGHT JOIN 右连接
✅ 适用场景:右表是主体,右表全部保留,左表匹配不到为 NULL
等价写法:
A RIGHT JOIN B=B LEFT JOIN A
业务例子:所有订单,关联用户信息(脏订单、用户已删除的订单也要查出来)
-- 右连接写法
SELECT u.name, o.order_no
FROM user u
RIGHT JOIN `order` o ON u.id = o.user_id;
-- 推荐改成左连接,可读性更好
SELECT u.name, o.order_no
FROM `order` o
LEFT JOIN user u ON o.user_id = u.id;
👉 结论:业务代码里基本杜绝 RIGHT JOIN,调整表顺序改用 LEFT JOIN
三、一张速查表
四、补充一个高频面试总结
先确定结果的主数据集是谁,主表放 FROM 后面,优先 LEFT JOIN
需求描述带:“全部、所有、包含没有 xx 的” → 外连接(LEFT)
需求描述带:“有 xx 的、存在 xx 的、同时满足” → INNER JOIN
右连接只适合临时调试看数据,正式 SQL 尽量不用
五、延伸:什么时候用 FULL OUTER JOIN(全外连接)
两边不匹配的数据都保留,MySQL 原生不支持,一般用 UNION 模拟;业务里极少用到。
本文原创作者:易君召,详见:https://www.yijunzhao.cc/about,转载请注明出处。
原文链接
欢迎访问