想象你手上有两张表:
示例数据
员工表 Employees:
员工ID | 姓名 | 部门ID
--------|---------|--------
1 | 张三 | 10
2 | 李四 | 20
3 | 王五 | 30
4 | 赵六 | NULL
部门表 Departments:
部门ID | 部门名称
--------|----------
10 | 技术部
20 | 销售部
50 | 人事部
1. **INNER JOIN(内连接)** - 只要"匹配的"
inner可以省略
SELECT e.姓名, d.部门名称
FROM Employees e
INNER JOIN Departments d ON e.部门ID = d.部门ID;
结果:
姓名 | 部门名称
--------|----------
张三 | 技术部
李四 | 销售部
解释 :只返回两张表都有匹配的记录。王五(部门ID=30)和赵六(部门ID=NULL)没有匹配的部门,所以不显示。
2. **LEFT JOIN(左连接)** - "左边的全要,右边的能配上就配"
SELECT e.姓名, d.部门名称
FROM Employees e
LEFT JOIN Departments d ON e.部门ID = d.部门ID;
结果:
姓名 | 部门名称
--------|----------
张三 | 技术部
李四 | 销售部
王五 | NULL ← 部门ID=30没找到
赵六 | NULL ← 部门ID=NULL
解释 :以**左表(Employees)**为主,左表所有记录都显示,右表匹配不上就显示NULL。
3. **RIGHT JOIN(右连接)** - "右边的全要,左边的能配上就配"
SELECT e.姓名, d.部门名称
FROM Employees e
RIGHT JOIN Departments d ON e.部门ID = d.部门ID;
结果:
姓名 | 部门名称
--------|----------
张三 | 技术部
李四 | 销售部
NULL | 人事部 ← 部门ID=50没员工
解释 :以**右表(Departments)**为主,右表所有记录都显示,左表匹配不上就显示NULL。
4. **FULL JOIN(全连接)** - "我全都要"
SELECT e.姓名, d.部门名称
FROM Employees e
FULL JOIN Departments d ON e.部门ID = d.部门ID;
结果:
姓名 | 部门名称
--------|----------
张三 | 技术部
李四 | 销售部
王五 | NULL ← 员工有,部门无
赵六 | NULL ← 员工有,部门无
NULL | 人事部 ← 部门有,员工无
解释:左右表所有记录都显示,匹配不上就用NULL补全。
5. **CROSS JOIN(交叉连接)** - "所有组合"
SELECT e.姓名, d.部门名称
FROM Employees e
CROSS JOIN Departments d;
结果:4个员工 × 3个部门 = 12行
姓名 | 部门名称
--------|----------
张三 | 技术部
张三 | 销售部
张三 | 人事部
李四 | 技术部
李四 | 销售部
李四 | 人事部
... | ...
ON 条件怎么理解?
ON条件就像是连接条件,告诉数据库怎么把两表的行"配对"。
例子1:等值连接(最常用)
ON e.部门ID = d.部门ID
把员工表的部门ID和部门表的部门ID相等的行连在一起。
例子2:不等连接
ON e.工资 > d.最低工资
连接那些员工工资大于部门最低工资的行。
例子3:多条件连接
ON e.部门ID = d.部门ID
AND e.入职日期 > '2020-01-01'
既要部门ID相等,又要员工是2020年以后入职的。
JOIN 执行顺序可视化
FROM 左表
LEFT JOIN 右表 ON 连接条件
WHERE 过滤条件
重要区别:
-
ON:连接时的匹配条件(决定怎么连) -
WHERE:连接后的过滤条件(决定显示哪些)
示例对比:
-- ON 影响连接结果
SELECT *
FROM A LEFT JOIN B
ON A.id = B.id AND B.status = 'active';
-- 先按条件连接,再显示所有A的记录
-- WHERE 在连接后过滤
SELECT *
FROM A LEFT JOIN B ON A.id = B.id
WHERE B.status = 'active';
-- 先连接,然后过滤掉B.status不是active的行
-- 注意:这会把B为NULL的行也过滤掉!
记忆口诀:
-
INNER JOIN:只要"配对的"
-
LEFT JOIN:左表全要,右边"爱配不配"
-
RIGHT JOIN:右表全要,左边"爱配不配"
-
FULL JOIN:两个全要,"不配就NULL"
-
ON:是"介绍人",负责两边怎么认识
-
WHERE:是"家长",见面后还要筛选
实战建议:
-
大部分情况用 LEFT JOIN(以主表为基准)
-
明确知道只要交集用 INNER JOIN
-
ON条件尽量用索引字段(如ID) -
复杂的过滤放
WHERE,简单的匹配放ON