SQL 中的连接:内连接与外连接

227 阅读3分钟

最近在做关于模型相关的工作梳理关系新的思路, 在 SQL 中,连接是一种用于组合两个或多个表的行的操作。连接可以分为内连接(INNER JOIN)和外连接(OUTER JOIN)。在本文中,我们将介绍这两种连接类型以及外连接的子类别:左连接(LEFT OUTER JOIN)、右连接(RIGHT OUTER JOIN)和全连接(FULL OUTER JOIN)。

内连接(INNER JOIN)

内连接只返回两个表中具有匹配关系的记录。换句话说,只有当左表(第一个表)和右表(第二个表)中的行满足连接条件时,它们才会出现在结果集中。如果左表或右表中的某行没有满足连接条件的关联行,那么这些行将不会出现在结果集中。

示例:

假设我们有以下两个表:

employees 表:

idname
1Alice
2Bob
3Carol

departments 表:

iddepartment_name
1HR
2IT
3Finance

我们可以使用内连接查询员工及其所属部门:

SELECT employees.name, departments.department_name
FROM employees
INNER JOIN departments
ON employees.department_id = departments.id;

结果集:

namedepartment_name
AliceHR
BobIT
CarolFinance

外连接(OUTER JOIN)

外连接可以进一步分为左连接(LEFT OUTER JOIN)、右连接(RIGHT OUTER JOIN)和全连接(FULL OUTER JOIN)。

左连接(LEFT OUTER JOIN)

左连接返回左表(第一个表)中的所有记录,即使右表(第二个表)中没有匹配的记录。如果右表中没有匹配的记录,那么结果集中对应的右表列将显示为 NULL 值。

示例:

假设我们有以下两个表:

employees 表:

idnamedepartment_id
1Alice1
2Bob2
3Carol3
4DavidNULL

departments 表:

iddepartment_name
1HR
2IT
3Finance

我们可以使用左连接查询员工及其所属部门,即使某些员工没有分配部门:

SELECT employees.name, departments.department_name
FROM employees
LEFT OUTER JOIN departments
ON employees.department_id = departments.id;

结果集:

namedepartment_name
AliceHR
BobIT
CarolFinance
DavidNULL

右连接(RIGHT OUTER JOIN)

右连接返回右表(第二个表)中的所有记录,即使左表(第一个表)中没有匹配的记录。如果左表中没有匹配的记录,那么结果集中对应的左表列将显示为 NULL 值。

示例:

假设我们有以下两个表:

employees 表:

idnamedepartment_id
1Alice1
2Bob2
3Carol3

departments 表:

iddepartment_name
1HR
2IT
3Finance
4Marketing

我们可以使用右连接查询员工及其所属部门,即使某些部门没有员工:

SELECT employees.name, departments.department_name
FROM employees
RIGHT OUTER JOIN departments
ON employees.department_id = departments.id;

结果集:

namedepartment_name
AliceHR
BobIT
CarolFinance
NULLMarketing

全连接(FULL OUTER JOIN)

全连接返回两个表中的所有记录。如果某个表中的记录在另一个表中没有匹配的记录,那么结果集中对应的另一个表的列将显示为 NULL 值。

注意: 并非所有数据库系统都支持全连接。例如,MySQL 不支持全连接,但可以使用联合(UNION)来实现类似的功能。

示例:

假设我们有以下两个表:

employees 表:

idnamedepartment_id
1Alice1
2Bob2
3Carol3
4DavidNULL

departments 表:

iddepartment_name
1HR
2IT
3Finance
4Marketing

在支持全连接的数据库系统中,我们可以使用全连接查询员工及其所属部门,即使某些员工没有分配部门或某些部门没有员工:

SELECT employees.name, departments.department_name
FROM employees
FULL OUTER JOIN departments
ON employees.department_id = departments.id;

结果集:

namedepartment_name
AliceHR
BobIT
CarolFinance
DavidNULL
NULLMarketing