本文概述
在用SQL进行数据分析期间, 你经常需要查看多个表并将它们连接起来以获得所需的结果。连接表以分析数据也是数据科学家必需的技能。在本教程中, 你将学习可以在PostgreSQL中执行的不同类型的连接。你将首先研究SQL中连接的初步概念, 然后了解不同类型的连接及其在PostgreSQL中的语法。你将通过使用两个表执行各种类型的连接查询来结束本教程。为了能够继续学习, 你应该熟悉SQL的基础知识以及如何在PostgreSQL中编写简单的查询。如果你正在寻找资源, 请学习这些资源, 以下资源可能会有用-
- PostgreSQL初学者指南
- srcmini的SQL for Data Science课程简介
让我们开始。
在PostgreSQL中设置数据库环境
在学习SQL连接的基础知识之前, 最好为分析创建一些表。你将需要至少两个具有至少一列相同之处的表。尽管你可以在同一张表上执行自连接查询, 但让我们暂时忽略这一事实。
你可以在pgAdmin工具上执行所有SQL操作, 该工具通常随PostgreSQL一起安装。如果没有可用的数据库, 请打开pgAdmin并创建一个数据库(给它一个选择的名称)以创建表。然后, 你可以按照给定的规格创建以下两个表-
- student_name(ID, 姓名)
- student_stream(id, 流)
请注意, 两个表的ID列相同。你可以使用以下CREATE语句创建表-
- 对于student_name-
创建表student_name(id smallint, 名称” char” []); - 对于student_stream-
创建表student_stream(id smallint, 流” char” []);
现在让我们将一些记录插入表中。
- 对于student_name-
INSERT INTO student_name(id, name) VALUES (1, 'Sayak');
INSERT INTO student_name(id, name) VALUES (2, 'Alex');
INSERT INTO student_name(id, name) VALUES (3, 'Sameer');
INSERT INTO student_name(id, name) VALUES (4, 'Rick');
- 对于student_stream-
INSERT INTO student_stream(id, stream) VALUES (1, 'CS');
INSERT INTO student_stream(id, stream) VALUES (1, 'IT');
INSERT INTO student_stream(id, stream) VALUES (2, 'ECE');
INSERT INTO student_stream(id, stream) VALUES (9, 'ECE');
如果你执行以上查询而不更改任何内容, 则表条目应类似于以下内容:
现在你已经准备好两个简单的表。现在, 让我们继续研究SQL连接的基础。
SQL连接-基础
SQL连接使你可以使用公共标识符来整理两个或多个(有时只有一个表)表。以你创建的上述两个表为例-两个表的ID列相同。你可能会质疑是否需要连接SQL。让我们简要讨论一下。
由于标准化的限制, 你可能没有在一张表中显示所有必需的信息。标准化不仅是理想的, 而且对于保持一致性, 减少冗余并防止多次插入和更新异常也是必需的。再次考虑以上两个表。假设你希望找出Sayak已注册的流。要获得此问题的答案, 你需要将两个表连接起来(也可以使用子查询, 但现在不要考虑), 然后进行相应处理。
对于要连接的两个表, 两者之间必须有一些共同点。这是否意味着两个表必须至少具有相同名称的一列?或究竟是什么情况?
你希望连接的表可能没有相同名称的列, 但在逻辑上它们应该相同, 即它们的数据类型应该相同。你不能连接两个具有相同名称但数据类型不同的列的表。现在让我们研究不同类型的SQL连接。
不同类型的SQL连接
在本部分中, 你将研究几种类型的SQL连接-
- 内部连接
- 自连接
- 外连接
- 左连接
- 左连接
- 完全连接
- 交叉连接
- 半连接和反连接
PostgreSQL为所有大写字母中提到的连接类型提供了单独的关键字。让我们逐一研究它们。为此, 你将首先以可视方式研究连接, 然后在PostgreSQL中执行相应的连接查询。
内部连接
查看下图, 以便直观地了解INNER JOIN-
在上面的示例中, 正在考虑的列是id列。 INNER JOIN将忽略在两个表中都不通用的其余列。现在, 让我们在PostgreSQL中执行一个查询, 该查询将在两个表-student_name和student_stream之间执行INNER JOIN。
执行以下查询后, 你将获得上图所示的结果-
SELECT s1.id, s1.name, s2.stream
FROM student_name AS s1
INNER JOIN student_stream AS s2
ON s1.id = s2.id;
s1和s2是两个表的别名。你将ON关键字与INNER JOIN一起使用。该查询也可以使用USING关键字执行-
SELECT s1.id, s1.name, s2.stream
FROM student_name AS s1
INNER JOIN student_stream AS s2
USING (id);
自连接允许你执行连接同一表。但是, 这可能是一个不错的选择吗?假设你有一个包含以下各列的表格-
- 国家
- 大陆
现在, 你要以两个大陆相同的方式招募两个国家。下图应该使你对预期结果有所了解-
外连接
OUTER JOIN可以进一步分为三种类型-
左连接或左连接:下图使你对SQL中的左连接有了一个清晰的了解-
请注意, 与INNER JOIN不同, LEFT JOIN从左侧的表(从w到你在查询中指定的顺序)获取记录, 而在右侧的表中没有任何匹配的条目。反过来, 这告诉你Sameer和Rick尚未注册任何流。相应的查询将是-
SELECT s1.id, s1.name, s2.stream
FROM student_name AS s1
LEFT JOIN student_stream AS s2
ON s1.id = s2.id;
RIGHT JOIN或Right Outer JOIN:RIGHT JOIN与LEFT JOIN相反-
RIGHT JOIN可以帮助你找到没有学生注册的信息流。该查询将是-
SELECT s1.id, s1.name, s2.stream
FROM student_name AS s1
RIGHT JOIN student_stream AS s2
ON s1.id = s2.id;
完全连接或完全外部连接:完全连接可让你将左连接和右连接合并为一个编译-
相应的查询将是-
SELECT s1.id, s1.name, s2.stream
FROM student_name AS s1
FULL JOIN student_stream AS s2
ON s1.id = s2.id;
请注意, 你可以使用USING关键字执行上述所有OUTER JOIN查询。现在让我们学习CROSS JOIN。
交叉连接
CROSS JOIN本质上是使用SQL表示的两个元素之间的笛卡尔乘积。假设你需要在两个表之间甚至单个表中具有所有可能的组合。为此, 你将需要CROSS JOIN。下图直观地展示了这个概念-
你已经有两个表可以对此进行测试。为了使student_name和student_stream表的id列之间具有所有可能的组合, 可以执行以下查询-
SELECT s1.id, s2.id
FROM student_name AS s1
CROSS JOIN student_stream AS s2;
然后你得到以下结果-
现在, 让我们看一下其他两种类型的连接, 而PostgreSQL不提供任何直接关键字。
半连接和反连接
让我们考虑一下你在本教程前面创建的表:
半连接查询通常以子查询的形式执行, 其中相对于第二张表中匹配的条件(或一组条件)从第一张表中拾取行。假设左表是第一个表, 右表是第二个表。
反连接查询是完全相反的。在”反连接”中, 针对第二张表中不匹配的条件(或一组条件)从第一张表中拾取行。这是一个图表, 你可以从视觉上理解它-
用于实现半连接的查询为-
select id, name
from student_name
where id IN
(select id from student_stream where stream
IN ('CS', 'IT', 'ECE'));
同样, 在这种情况下, 实现”反连接”的查询为-
select id, name
from student_name
where id NOT IN
(select id from student_stream where stream
IN ('CS', 'IT', 'ECE'));
注意上面的查询不是使用NOT。
使你的SQL Join向导更上一层楼
这就是本教程的全部内容。你在本教程中研究了一堆不同类型的SQL Joins, 并熟悉了它们的PostgreSQL语法。如果要练习一些具有挑战性的SQL Join练习, 则应参加SQL课程中的srcmini的Joining Data。实际上, 本课程的材料被用作制作本教程的参考。
在”评论”部分中让我知道你的问题。
评论前必须登录!
注册