什么是 SQL 连接?SQL 连接的类型详解
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
本文由 Christina Kopecky 撰写,最初发表于 Educative, Inc.。
结构化查询语言 (SQL)允许我们对关系数据库中的单个表执行各种操作。这些操作可以更新、创建、删除或选择该表中的记录。
如果我们有两个表,分别包含同一个人的不同信息,并且我们想将所有这些信息都显示在这个人的发票上,该怎么办?我们需要使用连接子句来实现这一点。
在本教程中,我们将定义什么是连接子句,讨论连接子句的类型,并给出每种连接子句的示例。
什么是 SQL 连接?
SQL 连接语句允许我们同时访问两个或多个表中的信息。它们还能保持数据库的规范化。规范化可以降低数据冗余,从而减少在删除或更新记录时应用程序中出现的数据异常。
简而言之: JOIN 子句允许我们根据相关列将两个或多个表中的行合并在一起。
让我们以上述客户及其订单为例进行说明。假设我们有一个包含客户信息的“客户”表和一个单独的“订单”表:
请注意,这些表格中有很多相同的信息。使用连接语句可以大大减少这些重复值。我们的新表格可能如下所示:
我们可以使用连接子句查询数据库,从 Customers 表中选择信息,从 Orders 表中选择信息,以便在我们的应用程序中需要的地方使用。
根据您的需求,连接语句有多种类型。下一节我们将介绍每种类型的示例。
连接语句的类型
您使用的连接语句类型取决于您的具体使用场景。连接操作共有四种不同的类型:
- (内连接):返回两个表中值匹配的数据集
- LEFT (OUTER) JOIN:返回左表中的所有记录以及右表中匹配的记录。
- 右(外)连接:返回右表中的所有记录以及左表中匹配的记录。
- 完全(外)连接:当左表或右表中存在匹配项时,返回所有记录。
内连接
如果将每张表想象成维恩图中的一个单独的圆,那么内连接就是两个圆相交的阴影区域。
INNER JOIN 关键字会选择满足连接条件的所有表行。该关键字会创建一个结果集,其中包含两个表中存在公共字段的行。
以下是内连接的语法:
SELECT column_name(s)
FROM table1
INNER JOIN table2
ON table1.column_name = table2.column_name;
此示例将忽略所有值为 NULL 的条目。此处的代码已简化。完整代码请参见原文。
create table Customers (
customer_id INT,
first_name VARCHAR(50),
last_name VARCHAR(50),
address VARCHAR(50),
city VARCHAR(50),
state VARCHAR(50),
zip_code VARCHAR(50),
email VARCHAR(50),
PRIMARY KEY(customer_id)
);
insert into Customers (customer_id, first_name, last_name, address, city, state, zip_code, email) values (1, 'Windham', 'McKevitt', '73 Namekagon Park', 'Washington', 'DC', '20525', 'wmckevitt0@example.com');
create table Orders (
order_id INT,
order_date VARCHAR(50),
amount VARCHAR(50),
customer_id INT,
PRIMARY KEY(order_id)
);
insert into Orders (order_id, order_date, amount, customer_id) values (34, '07-11-2020', '$56.34', 1);
select first_name, last_name, order_date, amount
from Customers c
inner join Orders o
on c.customer_id = o.customer_id
ORDER BY order_date
右外关节
此连接语句从表 B 中提取所有记录(无论是否包含 NULL 值),并从表 A 中提取匹配的列。
右连接返回最右侧表的所有行以及最左侧表的匹配行。右连接也称为右外连接。语法如下:
SELECT column_name(s)
FROM table1
RIGHT JOIN table2
ON table1.column_name = table2.column_name;
这里,客户表是表 A,订单表是表 B。此处的代码已简化,完整代码请参见原文。
create table Customers (
customer_id INT,
first_name VARCHAR(50),
last_name VARCHAR(50),
address VARCHAR(50),
city VARCHAR(50),
state VARCHAR(50),
zip_code VARCHAR(50),
email VARCHAR(50),
PRIMARY KEY(customer_id)
);
insert into Customers (customer_id, first_name, last_name, address, city, state, zip_code, email) values (1, 'Windham', 'McKevitt', '73 Namekagon Park', 'Washington', 'DC', '20525', 'wmckevitt0@example.com');
create table Orders (
order_id INT,
order_date VARCHAR(50),
amount VARCHAR(50),
customer_id INT,
PRIMARY KEY(order_id)
);
insert into Orders (order_id, order_date, amount, customer_id) values (34, '07-11-2020', '$56.34', 1);
select first_name, last_name, order_date, amount
from Customers c
right join Orders o
on c.customer_id = o.customer_id
ORDER BY order_date;
左外连接
左连接与右连接类似。左连接返回最左侧表的所有行以及最右侧表中与之匹配的行。语法如下:
SELECT column_name(s)
FROM table1
LEFT JOIN table2
ON table1.column_name = table2.column_name;
在这个例子中,列出了 Customers 表中的所有记录(无论是否包含 NULL 值),以及 Orders 表中对应的列。这里的代码已经简化,完整代码请参见原文。
create table Customers (
customer_id INT,
first_name VARCHAR(50),
last_name VARCHAR(50),
address VARCHAR(50),
city VARCHAR(50),
state VARCHAR(50),
zip_code VARCHAR(50),
email VARCHAR(50),
PRIMARY KEY(customer_id)
);
insert into Customers (customer_id, first_name, last_name, address, city, state, zip_code, email) values (1, 'Windham', 'McKevitt', '73 Namekagon Park', 'Washington', 'DC', '20525', 'wmckevitt0@example.com');
create table Orders (
order_id INT,
order_date VARCHAR(50),
amount VARCHAR(50),
customer_id INT,
PRIMARY KEY(order_id)
);
insert into Orders (order_id, order_date, amount, customer_id) values (34, '07-11-2020', '$56.34', 1);
select first_name, last_name, order_date, amount
from Customers c
left join Orders o
on c.customer_id = o.customer_id
ORDER BY order_date;
完全加入
全连接也称为全外连接。这意味着查询会将两个表中的数据合并,并返回所有记录,无论其中是否存在 NULL 值。
FULL JOIN 通过合并左连接和右连接的结果来创建一个结果集,其中包含所有行。对于不匹配的行,结果集(连接后的表)将显示 NULL 值。语法如下:
SELECT column_name(s)
FROM table1
FULL OUTER JOIN table2
ON table1.column_name = table2.column_name
WHERE condition;
注意:通常情况下不会使用全连接,这或许可以解释为什么 MySQL 不支持全连接。不过,也有一些例外情况需要用到全连接。
例如,查看未关联到客户或尚未下过任何订单的客户下的订单条目。
接下来要学什么?
恭喜你学会了如何在 SQL 中使用连接(JOIN)。这项简单的技能可以大大简化你的 SQL 编码工作。但你还有更多知识需要学习。下一步是:
- 交叉连接
- 与通配符连接
- 外键连接
- 高级 SQL
想阅读更多博客?订阅我们的博客简讯,即可每两个月收到一份包含编程技巧、热门文章、特邀作者等内容的合集。
学习愉快!


