什么是自连接?举例说明业务场景。
JOIN
考察意图
考察候选人是否把 JOIN 理解成「两份行集按键对齐」,而不是「必须两张不同的表」。自连接是组织树、配对、找前后事件的高频手法,答得出场景和别名,才说明真会用。
回答框架
- 先定义:同一张表当两份行集来 JOIN,必须各自取别名。
- 说清为什么需要它:一行要同时看到「自己」和「另一行」的字段。
- 举 1–2 个业务例子:员工-经理、用户邀请人、同日配对。
- 补一句边界:多层层级更适合递归 CTE;一对多要防行膨胀。
参考答案(口述版)
一句话:自连接就是把同一张表当两份数据来 JOIN。表还是那张表,但你给它两个别名,让每一行去对齐「另一行」。
为什么需要:SQL 一次只看见当前行。当你要同时拿到「我」和「跟我有关系的那一行」(上级、邀请人、上一笔订单、配对用户)时,就把表再挂一次。
经典场景 1:员工表找直属经理。
SELECT e.name AS employee, m.name AS manager
FROM staff e
LEFT JOIN staff m ON e.manager_id = m.id;
用 LEFT JOIN,是因为老板没有上级,INNER 会把顶层丢掉。
经典场景 2:邀请关系 / 同城配对。用户表自己连自己:u.inviter_id = i.id 拿邀请人;或 a.city = b.city AND a.id < b.id 做去重配对,避免 (A,B) 和 (B,A) 各出一次。
口述加分:自连接的本质不是「特殊 JOIN」,而是「同一实体扮演两个角色」。别名就是角色名:员工 vs 经理、被邀请人 vs 邀请人。层级超过一两层,优先递归 CTE,别把自连接叠成五六次。
关键词
别名同一张表员工-经理LEFT JOIN配对去重
面试官可能的追问
追问 1:组织树要查「所有下级」而不是直属上级,还用自连接吗?
直属一层用自连接就够。整棵子树要用递归 CTE(WITH RECURSIVE)或闭包表。硬把自连接写 N 次只能覆盖固定深度,层级一变就漏人。
追问 2:自连接为什么特别容易把行数打爆?
因为是一对多再对多。条件太松(只按城市、只按日期)会接近笛卡尔积。配对题要加 a.id < b.id 去重;聚合前先确认粒度,必要时先收窄再 JOIN。
常见踩坑
- 同一张表不写别名,引擎无法区分两份行集
- 员工-经理用 INNER JOIN,把没有上级的顶层过滤掉
- 配对条件缺
id </id <>,结果翻倍或自己连自己
记忆锚点
自连接是同一张表扮演两个角色;别名就是角色名。