MySQL JOIN 图解:INNER、LEFT 与 RIGHT 的区别
MySQL JOIN 图解:INNER、LEFT 与 RIGHT 的区别
学 SQL 的时候,单表查询都挺顺,一到多表 JOIN 就开始晕。其实 JOIN 没那么玄乎,准备两张小表亲手跑一遍,比看十篇理论文章都管用。
准备两张表
-- 用户表
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(20)
);
INSERT INTO users VALUES (1, '张三'), (2, '李四'), (3, '王五');
-- 订单表(user_id 关联用户)
CREATE TABLE orders (
id INT PRIMARY KEY,
user_id INT,
amount DECIMAL(10, 2)
);
INSERT INTO orders VALUES (101, 1, 99.00), (102, 1, 25.50), (103, 2, 200.00), (104, 99, 10.00);
注意两个刻意的安排:王五(id=3)没有订单;订单 104 的 user_id=99 在 users 表里不存在。这两个"边缘数据"最能暴露各种 JOIN 的差异。
INNER JOIN:只要两边都有的
SELECT u.name, o.amount
FROM users u
INNER JOIN orders o ON u.id = o.user_id;
结果是 3 行:张三两笔、李四一笔。王五和订单 104 都被丢弃——INNER JOIN 取的是交集。
LEFT JOIN:左表一行都不能少
SELECT u.name, o.amount
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;
结果 4 行,王五也会出现,amount 是 NULL。LEFT JOIN 保证左表全量保留,右表匹配不上的补 NULL。RIGHT JOIN 反过来,把 orders 放右边就是"订单全量保留",users 匹配不上补 NULL(订单 104 会显示 name 为 NULL)。
实际开发里 LEFT JOIN 用得最多,RIGHT JOIN 基本都可以通过交换表顺序改写成 LEFT JOIN,团队里一般约定统一用 LEFT。
ON 和 WHERE 过滤的区别(LEFT JOIN 的大坑)
这是踩过坑才记住的:对右表的条件,写在 ON 里和写在 WHERE 里结果完全不同。
-- A:条件写在 ON 里
SELECT u.name, o.amount
FROM users u
LEFT JOIN orders o ON u.id = o.user_id AND o.amount > 50;
-- B:条件写在 WHERE 里
SELECT u.name, o.amount
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE o.amount > 50;
- A 仍然是 3 个用户全在,只是李四那行 amount 变 NULL——ON 只影响"右表匹配哪些行",不影响左表保留
- B 只剩张三一行——WHERE 是 JOIN 完成之后再过滤,amount 为 NULL 的行直接被滤掉,LEFT JOIN 退化成了 INNER JOIN
想要"所有用户及其大额订单(没有则为 NULL)"用 A;想要"有大额订单的用户"用 B。语义完全不同,写之前先想清楚。
FULL OUTER JOIN?
MySQL 不支持 FULL OUTER JOIN,需要时用 UNION 拼:
SELECT u.name, o.amount FROM users u LEFT JOIN orders o ON u.id = o.user_id
UNION
SELECT u.name, o.amount FROM users u RIGHT JOIN orders o ON u.id = o.user_id;
这样王五和订单 104 都能出现。UNION 自带去重,LEFT 和 RIGHT 的结果集本来不相交,所以不用担心重复。
小结
| JOIN 类型 | 结果集 | 典型场景 |
|---|---|---|
| INNER | 两边都匹配的行 | 只关心有效关联 |
| LEFT | 左表全部 + 右表匹配 | 主表带可选明细(用户-订单) |
| RIGHT | 右表全部 + 左表匹配 | 少用,改写成 LEFT |
| FULL(UNION 模拟) | 两边全量 | 数据对账 |
最后一个建议:JOIN 的字段一定要确认两边都有索引,小表演示无所谓,上了生产几万行的表没索引的 JOIN 就是慢查询制造机。
看到这里了?如果这篇文章帮到过你
请我喝瓶可乐就好 🥤

评论0 条
还没有评论,来抢沙发~