1. 什么是 JOIN?
JOIN 是用来把两张表连接在一起的操作。它的作用是根据某个条件,将两张表中的数据组合起来。
举个例子:
假设我们有两张表:
表1:students
| student_id | name |
|---|---|
| 1 | Alice |
| 2 | Bob |
| 3 | Charlie |
表2:grades
| student_id | grade |
|---|---|
| 1 | A |
| 3 | B |
| 4 | C |
2. INNER JOIN
INNER JOIN 只取两张表中 匹配上的数据。
SELECT students.name, grades.grade
FROM students
INNER JOIN grades ON students.student_id = grades.student_id;
结果:
| name | grade |
|---|---|
| Alice | A |
| Charlie | B |
- 解释:只有
student_id在两张表中都存在的数据才会被保留。 - 不匹配的部分(比如
Bob或student_id = 4)会被丢弃。
3. LEFT JOIN
LEFT JOIN 会保留 左表的所有数据,即使右表没有匹配的数据。
SELECT students.name, grades.grade
FROM students
LEFT JOIN grades ON students.student_id = grades.student_id;
结果:
| name | grade |
|---|---|
| Alice | A |
| Bob | NULL |
| Charlie | B |
-
解释:
Alice和Charlie的student_id在两张表中都存在,所以匹配到了grade。Bob的student_id在右表中没有对应的记录,所以grade是NULL。
4. RIGHT JOIN
RIGHT JOIN 会保留 右表的所有数据,即使左表没有匹配的数据。
SELECT students.name, grades.grade
FROM students
RIGHT JOIN grades ON students.student_id = grades.student_id;
结果:
| name | grade |
|---|---|
| Alice | A |
| Charlie | B |
| NULL | C |
-
解释:
Alice和Charlie的student_id在两张表中都存在,所以匹配到了name。student_id = 4在左表中没有对应的记录,所以name是NULL。
5. FULL OUTER JOIN
FULL OUTER JOIN 会保留 两张表中所有的数据,不管是否匹配。
SELECT students.name, grades.grade
FROM students
FULL OUTER JOIN grades ON students.student_id = grades.student_id;
结果:
| name | grade |
|---|---|
| Alice | A |
| Bob | NULL |
| Charlie | B |
| NULL | C |
-
解释:
- 匹配上的数据(
Alice和Charlie)会保留。 - 左表中没有匹配的数据(
Bob)也会保留,grade是NULL。 - 右表中没有匹配的数据(
student_id = 4)也会保留,name是NULL。
- 匹配上的数据(
6. CROSS JOIN
CROSS JOIN 会生成 两张表的笛卡尔积,即每一行左表数据都会和右表的每一行配对。
SELECT students.name, grades.grade
FROM students
CROSS JOIN grades;
结果:
| name | grade |
|---|---|
| Alice | A |
| Alice | B |
| Alice | C |
| Bob | A |
| Bob | B |
| Bob | C |
| Charlie | A |
| Charlie | B |
| Charlie | C |
-
解释:
- 这里没有任何匹配条件,每一行左表的数据都和右表的每一行数据组合起来。
7. 总结表格
以下是各种 JOIN 的区别总结:
| JOIN 类型 | 匹配条件 | 保留左表数据 | 保留右表数据 | 不匹配的数据 |
|---|---|---|---|---|
| INNER JOIN | 匹配条件满足的数据 | 否 | 否 | 丢弃 |
| LEFT JOIN | 匹配条件满足的数据 + 左表数据 | 是 | 否 | 右表为空 |
| RIGHT JOIN | 匹配条件满足的数据 + 右表数据 | 否 | 是 | 左表为空 |
| FULL OUTER JOIN | 匹配条件满足的数据 + 所有数据 | 是 | 是 | 左右表均为空 |
| CROSS JOIN | 无条件组合 | 是 | 是 | 全部组合 |
8. 如何选择 JOIN?
-
INNER JOIN:只要两张表都有数据时才需要,丢弃不匹配的部分。- 例子:查询所有有成绩的学生。
-
LEFT JOIN:左表是主要表,需要保留左表的所有数据。- 例子:查询所有学生及他们的成绩,如果没有成绩,显示
NULL。
- 例子:查询所有学生及他们的成绩,如果没有成绩,显示
-
RIGHT JOIN:右表是主要表,需要保留右表的所有数据。- 例子:查询所有成绩及对应的学生,如果没有学生,显示
NULL。
- 例子:查询所有成绩及对应的学生,如果没有学生,显示
-
FULL OUTER JOIN:需要保留两张表的所有数据。- 例子:查询所有学生和所有成绩,甚至没有匹配时也要保留。
-
CROSS JOIN:需要所有组合的情况(几乎不常用)。- 例子:生成所有学生和所有成绩的配对。
完。