LEFT JOIN 与自连接,一篇彻底搞懂!
上一篇我们学习了 INNER JOIN 和 ON 的使用方法。本篇继续学习 JOIN 中最重要的两个知识点:
-
LEFT JOIN
-
Self Join(自连接)
这两类 JOIN 几乎覆盖了 LeetCode SQL 中绝大多数连接类题目。
一、为什么需要 LEFT JOIN?
INNER JOIN 的特点是:
只有两张表能够匹配的数据才会返回。
例如:
Person
| personId | name |
|---|---|
| 1 | Allen |
| 2 | Bob |
Address
| personId | city |
|---|---|
| 2 | New York |
如果执行:
SELECT *
FROM Person p
JOIN Address a
ON p.personId = a.personId;
结果:
| name | city |
|---|---|
| Bob | New York |
Allen 消失了。
为什么?
因为 Address 中没有 personId=1。
二、LEFT JOIN 的作用
LEFT JOIN 表示:
保留左表所有数据。
语法:
SELECT ...
FROM A
LEFT JOIN B
ON ...
执行逻辑:
-
先保留 A 的所有记录。
-
去 B 中寻找对应记录。
-
找到则拼接。
-
找不到则填充 NULL。
例如:
SELECT
p.firstName,
p.lastName,
a.city,
a.state
FROM Person p
LEFT JOIN Address a
ON p.personId = a.personId;
结果:
| firstName | city |
|---|---|
| Allen | NULL |
| Bob | New York |
这正是 LeetCode 175《Combine Two Tables》的标准解法。
三、LEFT JOIN 与 INNER JOIN 的区别
INNER JOIN:
Person Address
Allen × 没有地址
Bob √ New York
返回:
Bob
LEFT JOIN:
Person Address
Allen ×
↓
Allen NULL
Bob √
↓
Bob New York
返回:
Allen
Bob
因此可以记一句口诀:
LEFT JOIN 保留左边。
四、什么时候一定要用 LEFT JOIN?
当题目出现下面这些描述时:
-
所有用户
-
所有员工
-
所有订单
-
即使没有......
-
如果不存在......
几乎都应该首先想到 LEFT JOIN。
例如:
显示所有员工及其奖金。
没有奖金也要显示员工。
那么:
Employee
LEFT JOIN Bonus
五、自连接(Self Join)
什么是自连接?
就是:
一张表和自己连接。
例如员工表:
| id | name | managerId |
|---|---|---|
| 1 | Alice | NULL |
| 2 | Bob | 1 |
| 3 | Tom | 1 |
managerId 指向的也是 Employee 表。
因此需要:
SELECT
e.name AS Employee,
m.name AS Manager
FROM Employee e
LEFT JOIN Employee m
ON e.managerId = m.id;
结果:
| Employee | Manager |
|---|---|
| Alice | NULL |
| Bob | Alice |
| Tom | Alice |
这里:
-
e 表示员工
-
m 表示经理
其实都是 Employee。
六、为什么要起别名?
如果写:
FROM Employee
JOIN Employee
数据库不知道:
哪一个 Employee 是员工。
哪一个 Employee 是经理。
所以必须:
Employee e
Employee m
这样:
e.id
m.id
就能区分。
七、LeetCode 高频题
① 175 Combine Two Tables
考点:
LEFT JOIN。
② 181 Employees Earning More Than Their Managers
考点:
自连接。
SELECT e.name
FROM Employee e
JOIN Employee m
ON e.managerId = m.id
WHERE e.salary > m.salary;
③ 查询每个员工及其经理
也是自连接。
八、常见错误
错误一
需要保留全部用户,却写成:
JOIN
正确:
LEFT JOIN
错误二
ON 条件写错。
例如:
ON id=id
应该:
ON e.managerId=m.id
错误三
忘记起别名。
自连接必须使用:
Employee e
Employee m
九、本章总结
今天学习了两个核心知识:
-
LEFT JOIN:保留左表所有数据,匹配不到返回 NULL。
-
Self Join:一张表连接自己,用于处理上下级、父子节点、好友关系等问题。
牢记一句口诀:
保留谁,就把谁放在 LEFT JOIN 左边。
下一篇,我们将正式进入 SQL 中非常重要的一类知识------子查询(Subquery)。