#22 SQL 简单

什么是自连接?举例说明业务场景。

JOIN

🎯 考察意图

考察候选人是否把 JOIN 理解成「两份行集按键对齐」,而不是「必须两张不同的表」。自连接是组织树、配对、找前后事件的高频手法,答得出场景和别名,才说明真会用。

📐 回答框架

  1. 先定义:同一张表当两份行集来 JOIN,必须各自取别名。
  2. 说清为什么需要它:一行要同时看到「自己」和「另一行」的字段。
  3. 举 1–2 个业务例子:员工-经理、用户邀请人、同日配对。
  4. 补一句边界:多层层级更适合递归 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 <>,结果翻倍或自己连自己

🧠 记忆锚点

自连接是同一张表扮演两个角色;别名就是角色名。