自连接是同一张表在from子句中出现多次以比较不同行,必须使用不同别名区分,如e和m;典型应用是查询员工及其上级,inner join返回有上级者,left join保留无上级者(如ceo),on条件需逻辑正确,索引可提升性能。

什么是自连接,为什么必须用别名
自连接就是让一张表在 FROM 子句里出现两次或多次,用来比较同一张表里的不同行。不加别名会直接报错——SQL 引擎根本分不清你写的 t1.id 和 t2.id 指的是哪一份数据。
- 别名不是可选项,是语法强制要求:没别名,
SELECT里的字段就无法明确归属 - 别名要短且有意义,比如
e表示员工(employee),m表示经理(manager) - 同一个表不能在同一个查询里重复使用相同别名,否则会触发“重复别名”错误
自连接的典型写法:INNER JOIN + 别名
最常用场景是查“员工及其直属上级”,假设表 employees 有 id、name、manager_id 字段:
SELECT e.name AS employee_name, m.name AS manager_name FROM employees e INNER JOIN employees m ON e.manager_id = m.id;
-
INNER JOIN只返回有上级的员工;如果想包含 CEO(manager_id为NULL),得换成LEFT JOIN -
ON条件里必须明确是“左表某字段 = 右表某字段”,不能写成e.id = m.id(除非你真想查自己管自己) - 别名一旦定义,后续所有引用都必须用它,不能再写
employees.name
LEFT JOIN 自连接:保留无匹配行的关键细节
当需要列出所有员工,不管有没有上级时,LEFT JOIN 是唯一选择:
SELECT e.name, m.name AS manager_name FROM employees e LEFT JOIN employees m ON e.manager_id = m.id;
-
m.name在 CEO 行会是NULL,这是预期行为,不是 bug - 如果你在
WHERE里加了m.name IS NOT NULL,就又退化成INNER JOIN效果,这个坑很多人踩 -
LEFT JOIN的“左”永远指FROM后面那个表(这里是e),顺序不能反
性能和索引:自连接慢?先看有没有索引
自连接本身不慢,慢是因为没走索引:
- 确保被用于
ON条件的字段有索引,比如manager_id和id都应建索引 -
EXPLAIN查执行计划时,注意type列是否为ref或eq_ref;如果是ALL,说明正在全表扫描右表 - 别名不影响性能,但别名太长可能让执行计划输出难读,无关紧要,但写
e和m比写emp_table_alias_1实在舒服些
自连接真正容易出问题的地方,不在语法,而在逻辑混淆——比如把 ON e.id = m.manager_id 写反,结果查出来是“谁是这个人的下属”,而不是“他的上级是谁”。这种错误不会报错,但结果完全不对。










