join是mysql中基于逻辑关系行级匹配的关联操作,不改变原表;inner join只返回双方匹配行,left join保留左表全量,full outer join需用union模拟,cross join易引发笛卡尔积风险,self join须注意别名与条件方向。

JOIN 是 MySQL 中用于把两个或多个表按条件关联起来查数据的操作,不是“拼表”,而是基于逻辑关系做行级匹配。
它不改变原表,只在查询时临时组合数据。用错类型,结果就漏数据、多数据,甚至查出完全不对的记录。
INNER JOIN 只返回双方都匹配的行
这是最常用也最容易被默认当成“万能连接”的类型。
常见错误现象:LEFT JOIN 写成 INNER JOIN 却没意识到会丢掉左表中无关联的记录;或者反过来,在统计“所有用户”时误用 INNER JOIN,导致未下单用户直接消失。
- 语法上
JOIN和INNER JOIN完全等价,但显式写INNER JOIN更利于团队理解意图 - 性能上,MySQL 通常会对
ON条件字段自动尝试索引优化,但前提是两表字段类型一致(比如都是INT,别一边是VARCHAR一边是INT) - 如果连接字段有大量
NULL值,INNER JOIN会直接跳过这些行——因为NULL = NULL判定为FALSE
LEFT JOIN 保证左表数据不丢失
左表全量输出,右表只补匹配项,不匹配就填 NULL。但很多人栽在 WHERE 子句里对右表字段加非空判断。
例如:SELECT * FROM orders LEFT JOIN users ON orders.user_id = users.id WHERE users.status = 'active' —— 这条语句实际把 LEFT JOIN 变成了 INNER JOIN,因为 WHERE 在连接后过滤,users.status 为 NULL 的行被干掉了。
- 想保留左表全部 + 只查右表中 status=active 的匹配项?得把条件挪到
ON里:ON orders.user_id = users.id AND users.status = 'active' -
LEFT JOIN的结果行数恒等于左表行数(不管右表有没有匹配),这是验证是否写对的重要依据 - 别用
RIGHT JOIN去“强行对齐”逻辑,90% 场景换成LEFT JOIN并调换表顺序更清晰
FULL OUTER JOIN 在 MySQL 中不存在
MySQL 原生不支持 FULL JOIN 或 FULL OUTER JOIN,直接写会报错:ERROR 1064 (42000): You have an error in your SQL syntax。
必须用 UNION 模拟:
SELECT a.*, b.* FROM table1 a LEFT JOIN table2 b ON a.id = b.id UNION SELECT a.*, b.* FROM table1 a RIGHT JOIN table2 b ON a.id = b.id WHERE a.id IS NULL;
- 注意:两个子查询字段顺序和数量必须严格一致,否则
UNION失败 -
UNION自动去重,如果要保留重复行,得用UNION ALL,但多数业务场景需要的是去重后的全集 - 性能比原生
FULL JOIN差不少,大表慎用;小表差异对比或数据迁移校验时才考虑
CROSS JOIN 和 SELF JOIN 是特殊但高频的场景
CROSS JOIN 不带 ON 条件,就是笛卡尔积,SELECT * FROM colors CROSS JOIN sizes 返回所有颜色×所有尺寸的组合。一不留神连个 WHERE 都没加,100 行 × 100 行 = 1 万行,线上查一次可能拖垮数据库。
SELF JOIN 是同一张表自己连自己,比如查员工和直属经理:SELECT e.name, m.name FROM employees e LEFT JOIN employees m ON e.manager_id = m.id。关键点在于必须给表起不同别名,否则字段无法区分。
-
CROSS JOIN后一定要跟WHERE或ON(即使只是ON 1=1)来限制结果集,否则就是隐患 -
SELF JOIN的ON条件容易写反(比如写成e.id = m.manager_id),结果就变成“找我的下属”而不是“找我的上司” - 层级较深的树形结构(如部门树、分类树)用
SELF JOIN只能查固定深度,超过 2 层就得考虑递归 CTE 或应用层处理
真正难的不是记住六种写法,而是每次写 JOIN 前问一句:我要的数据主干来自哪张表?哪些缺失值可以接受?哪些字段可能为 NULL?—— 这些判断错了,再漂亮的 SQL 也跑不出正确结果。











