自连接与交叉连接
表与自身连接、CROSS JOIN 笛卡尔积
自连接与交叉连接
表和自身做 JOIN、或不做任何关联条件——这两种特殊连接各有各的用武之地。
学完本章你将: 掌握自连接(查层级/去重/配对)、CROSS JOIN。
自连接 —— 表和自己 JOIN
经典场景:员工表有 manager_id 指向同一张表的 id。
sql
-- 员工名单 + 上级姓名
SELECT e.name AS 员工, m.name AS 上级
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id;
你需要给同一张表起两个不同的别名(e 和 m),SQL 才能区分"作为员工的那份"和"作为上级的那份"。
自连接去重
sql
-- 找出同名的用户对
SELECT a.name, a.id, b.id
FROM users a
INNER JOIN users b ON a.name = b.name AND a.id < b.id;
-- a.id < b.id 避免:1) 匹配到自己 2) 重复对
CROSS JOIN —— 笛卡尔积
不加 ON 条件,左表每一行和右表每一行配对。结果行数 = 左表行数 × 右表行数。
sql
-- 所有尺寸 × 所有颜色
SELECT s.size, c.color
FROM sizes s
CROSS JOIN colors c;
-- 3个尺寸 × 4个颜色 = 12行
⚠️ 两张 1000 行的表 CROSS JOIN = 100 万行。务必确认你确实需要它。
UNION —— 合并结果集
UNION 把两个 SELECT 的结果上下拼接(加行,不是加列)。
sql
-- 北京用户 + 上海用户
SELECT name, city FROM users WHERE city = '北京'
UNION
SELECT name, city FROM users WHERE city = '上海';
-- UNION ALL:保留重复行(更快)
SELECT name FROM users WHERE city = '北京'
UNION ALL
SELECT name FROM users WHERE city = '北京';
-- 如果一个人在北京出现两次,UNION ALL 保留重复,UNION 去重