学习数据库中的INNER JOIN
、LEFT JOIN
、RIGHT JOIN
,如有错误望诸位指正🧐。
在 SQL 中,INNER JOIN
、LEFT JOIN
和 RIGHT JOIN
是三种常用的表连接方式,它们的核心区别在于 如何处理连接条件中不匹配的行。
1. INNER JOIN
INNER JOIN
也就是是内连接,它的作用是返回两个表中 完全匹配 的行。它的逻辑是仅保留两个表中 连接条件成立 的行。如果某行在左表(出现在INNER JOIN
关键字左边的表)或右表(出现在INNER JOIN
关键字右边的表)中没有匹配项,则该行不会出现在结果中。最终返回的结果是两个表的交集部分。
比如说对于两张表
Employees 员工表
id | name | department_id |
---|---|---|
1 | 张三 | 101 |
2 | 李四 | 102 |
3 | 王五 | 103 |
Departments 部门表
id | name |
---|---|
101 | 技术部 |
102 | 销售部 |
103 | 财务部 |
执行SQL语句
SELECT A.id, B.name
FROM Employees A
INNER JOIN Departments B ON A.department_id = B.id;
我们先逐个分解一下这条SQL语句。
FROM Employees A
中FROM
关键字指定了主表也就是查询开始的表,Employees
是主表的名称,其后的A
为 Employees 表定义的别名。后续可以直接用 A 代替 Employees 。比方说 A.id 就等价于 Employees.id。
INNER JOIN Departments B
中的INNER JOIN
关键字表示内连接操作,Departments
指定了需要连接的表名。和上面的A
一样,B
为 Departments 表定义别名。后续可以直接用 B 代替 Departments。
ON A.department_id = B.id
中的ON
关键字,用于指定连接条件。ON A.department_id = B.id
的作用是将 Employees 表的 department_id 与 Departments 表的 id 匹配,只有匹配成功的行才会被保留。
FROM
关键字指定主表,而这里的主表理解为Employees A INNER JOIN Departments B on A.department_id = B.id
更好一点儿(继续看例子你会更容易明白)。
现在来看整个SQL语句(肯定不是水字数😘)
SELECT A.id, B.name
FROM Employees A
INNER JOIN Departments B ON A.department_id = B.id;
Employees A INNER JOIN Departments B ON A.department_id = B.id
会构建一张表,并且是将A中department_id等于B中id的行拼接成一行保留到这张表
A.id | A.name | A.department_id | B.id | B.name |
---|---|---|---|---|
1 | 张三 | 101 | 101 | 技术部 |
2 | 李四 | 102 | 102 | 销售部 |
3 | 王五 | 103 | 103 | 财务部 |
然后通过SELECT A.id, B.name FROM
抽取这张表中的A.id
和B.name
字段返回,最终得到结果为
A.id | B.name |
---|---|
1 | 技术部 |
2 | 销售部 |
3 | 财务部 |
2. LEFT JOIN
LEFT JOIN 又称为 LEFT OUTER JOIN,也就是左连接,它的作用是返回左表(出现在LEFT JOIN
关键字左边的表)的所有行,即使右表(出现在LEFT JOIN
关键字左边的表)中没有匹配的行。它会确保左表的所有行都会被保留,并且如果右表没有匹配的行,则右表字段用 NULL
填充。最终返回的结果是左表全集 + 右表匹配的行,而未匹配部分为填充为 NULL
。
比如说对于两张表
TableA
id | data |
---|---|
1 | Apple |
2 | Banana |
3 | Cherry |
TableB
id | info |
---|---|
1 | Red |
3 | Purple |
4 | Green |
执行 SQL 语句
SELECT A.id, B.info
FROM TableA A
LEFT JOIN TableB B ON A.id = B.id;
其中TableA A LEFT JOIN TableB B ON A.id = B.id
会构建一张表,并且它会确保 A (左表)的所有行都会被保留,并且如果B(右表)没有匹配的行,就用 NULL
填充
A.id | A.data | B.id | B.info |
---|---|---|---|
1 | Apple | 1 | Red |
2 | Banana | NULL | NULL |
3 | Cherry | 3 | Purple |
然后通过SELECT A.id, B.info FROM
从这张表中拿出A.id
和B.info
字段得到最终结果为
A.id | B.info |
---|---|
1 | Red |
2 | NULL |
3 | Purple |
3. RIGHT JOIN
RIGHT JOIN
又称RIGHT OUTER JOIN
,也就是右连接,它的作用是返回右表的所有行,即使左表中没有匹配的行(刚好和LEFT JOIN
相反)。它会确保右表的所有行都会被保留,并且如果左表没有匹配的行,左表字段用 NULL
填充。最终返回的结果是右表全集 + 左表匹配的行,未匹配部分为 NULL
。
比如说对于两张表
TableA
id | data |
---|---|
1 | X |
2 | Y |
3 | Z |
TableB
id | info |
---|---|
1 | Alpha |
3 | Beta |
4 | Gamma |
执行 SQL 语句
SELECT A.data, B.info
FROM TableA A
RIGHT JOIN TableB B ON A.id = B.id;
先通过TableA A RIGHT JOIN TableB B ON A.id = B.id
构建一张表
B.id | B.info | A.id | A.data |
---|---|---|---|
1 | Alpha | 1 | X |
3 | Beta | 3 | Z |
4 | Gamma | NULL | NULL |
然后通过SELECT A.data, B.info FROM
抽取A.data
和B.info
得到结果
A.data | B.info |
---|---|
X | Alpha |
Z | Beta |
NULL | Gamma |
4. 交换表位置 LEFT JOIN 与 RIGHT JOIN`等价
可以通过交换表的位置,用 LEFT JOIN
实现 RIGHT JOIN
的效果,也就是A RIGHT JOIN B
等价于B LEFTJOIN A
。
对比总结
连接类型 | 是否保留左表所有行? | 是否保留右表所有行? | 未匹配的字段填充 |
---|---|---|---|
INNER JOIN | ❌ | ❌ | 不保留未匹配行 |
LEFT JOIN | ✔️ | ❌ | 右表字段为 NULL |
RIGHT JOIN | ❌ | ✔️ | 左表字段为 NULL |