下面把这条语句拆成 5 个层次,逐句、逐词、逐字节地解释 LEFT JOIN
到底做了什么,以及为什么"左边"(Employees)会出现,而"右边"(EmployeeUNI)有可能缺失。
- 语法骨架
sql
SELECT EmployeeUNI.unique_id, Employees.name
FROM Employees
LEFT JOIN EmployeeUNI
ON Employees.id = EmployeeUNI.id;
SELECT ...
决定最终列:
只要两列:EmployeeUNI 里的 unique_id 与 Employees 里的 name。FROM Employees
先声明"左表"------一切数据行的起点。LEFT JOIN EmployeeUNI ON ...
把 EmployeeUNI 挂到 Employees 上,但以左表为准,哪怕右表没有匹配行,也要把左表行保留。
- 语义一句话
把 Employees 表里的 所有人都拿出来;如果某位员工在 EmployeeUNI 表里有 unique_id,就一并带上;如果没有,unique_id 填 NULL。
- 执行顺序(逻辑上)
- 先读 Employees 的每一行。
- 拿着当前行的
id
去 EmployeeUNI 找同 id 的行。- 找到 0 行 → unique_id 填 NULL,仍保留左行。
- 找到 1 行 → 把右行字段拼上去。
- 找到 n 行 → 左行复制 n 份,每份拼接不同的右行。
- 最终投影 SELECT 的两列。
- 与 INNER JOIN 的差别(图示)
假设两表数据:
Employees
id | name |
---|---|
1 | Alice |
2 | Bob |
3 | Carol |
EmployeeUNI
id | unique_id |
---|---|
1 | A-100 |
3 | C-300 |
-
LEFT JOIN 结果
左表 3 行全部保留,Bob 没有 unique_id → NULL
unique_id name A-100 Alice NULL Bob C-300 Carol -
INNER JOIN 结果
只保留两边都有匹配的行 → Bob 消失
unique_id name A-100 Alice C-300 Carol
- 常见疑问 & 陷阱
问题 | 解释 |
---|---|
为什么写 LEFT JOIN 而不是 LEFT OUTER JOIN ? |
OUTER 可省略,语义一样。 |
会不会把 EmployeeUNI 中多余的 id 也带进来? | 不会。若右表有多条匹配,会把左行复制多份;若右表 id 不在 Employees 里,这些行永远不会出现。 |
右表列重名怎么办? | 用表别名或列别名:SELECT eu.unique_id AS uid, e.name ... 。 |
性能注意点 | 连接列(id )最好都是主键或索引,避免全表扫描。 |
一句话总结
LEFT JOIN
的核心是"左表为王":先把 Employees 的所有人拿出来,再尝试从 EmployeeUNI 取 unique_id;取不到也留人,取得到就拼在一起。