MySQL JOIN 是基于列值匹配的横向拼接操作,包括 INNER、LEFT、RIGHT 三种基础类型及 LEFT JOIN 配合 WHERE IS NULL 的反连接用法;ON 决定如何连接,WHERE 过滤连接结果,二者不可混淆。

MySQL 中的 JOIN 用于把两个或多个表中的数据按关联条件组合起来,是查询多表数据最常用、最核心的操作。
JOIN 的本质:基于列值匹配的横向拼接
JOIN 不是简单地把表上下堆叠(那是 UNION),而是根据指定列(通常是主键和外键)的相等关系,将左表的每一行与右表中“匹配”的行横向连接成新记录。不匹配的行是否保留,取决于 JOIN 类型。
四种基础 JOIN 类型及用法
INNER JOIN(内连接):只返回左右两表都存在匹配值的记录。
示例: SELECT u.name, o.amount FROM users u INNER JOIN orders o ON u.id = o.user_id; —— 只查有下单记录的用户信息。
LEFT JOIN(左连接):返回左表全部记录,右表无匹配时对应字段为 NULL。
适用场景: 查所有用户,不管有没有订单;统计每个用户的订单数(含0单用户)。
RIGHT JOIN(右连接):返回右表全部记录,左表无匹配时为 NULL。实际中较少用,多数可改写为 LEFT JOIN(调换表顺序即可)。
LEFT JOIN + WHERE 右表字段 IS NULL(反连接):常用来查“在 A 表但不在 B 表”的数据。
例如: SELECT u.* FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE o.user_id IS NULL; —— 找出从未下过单的用户。
ON 和 WHERE 的关键区别
ON 条件决定“怎么连”:在连接过程中判断哪些行可以配对,影响连接结果集的结构(尤其对 OUTER JOIN)。
WHERE 条件决定“连完再筛”:在连接完成后的临时结果上做过滤,可能把 LEFT JOIN 原本保留的 NULL 行也过滤掉。
错误写法(会退化为 INNER JOIN 效果): SELECT * FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE o.status = 'paid'; —— 因为 WHERE 要求 o.status 存在且等于 'paid',NULL 行被排除。
正确写法(若想保留用户,同时只取已支付订单): 把条件移到 ON 中:... LEFT JOIN orders o ON u.id = o.user_id AND o.status = 'paid'。
实用建议与注意事项
- 优先使用 INNER JOIN 或 LEFT JOIN,避免 RIGHT JOIN,逻辑更直观
- 连接字段务必建立索引(尤其是外键列),否则大表 JOIN 性能急剧下降
- 别名(如
users u)强烈推荐,让 SQL 更简洁、可读性更高 - 多表 JOIN 时,注意连接顺序和条件链路,避免产生意外笛卡尔积(如漏写 ON 条件)










