什么是SQL Join?

SQL连接是两个SQL表的逻辑组合。有许多方法可以将表连接在一起,其中大多数都涉及到寻找两者之间的公共值。SQL连接使规范化成为可能,因为它们允许查询返回跨越多个表的结果。

SQL Join如何工作?

当SQL查询包含连接时,RDBMS将在连接中包括的所有表中搜索数据。然后,它将查询结果组合成统一的格式,使它们看起来好像来自单个多列表。

为了理解这是如何工作的,我们必须考虑关系数据库如何尽可能地减少冗余。例如,一家公司可能会在电子表格中保存员工记录,看起来像这样:

未定义的

这种储存方法不是很有效。如果对任何部门进行了更改,则数据库所有者将需要更新每条记录。在大范围内,这可能会降低进程的速度,并存在数据丢失的风险。

在关系数据库中,管理员将使用归一化将它分解成具有不重复值的小表,如下所示:

未定义的

这是两个单独的表,包含不重复的值。数据之间的逻辑关系仍然通过主键关系存在,即本例中的新DEPT_ID字段。数据库所有者可以独立地管理它们,只要它们保持了这种关系。

但是,有时用户需要完整的员工记录,包括员工所在部门的完整详细信息。我们通过使用SQL连接来实现这一点。

SQL Join的类型是什么?

SQL开发人员可以向查询添加连接,以创建极其复杂的视图。在本例中,我们将重点关注上面非常基本的测试数据,以说明不同类型的连接是如何工作的。

连接有一个左表和一个右表,右表只是指它们出现在连接命令的一侧。因此,如果开发人员写“SELECT * FROM tableA JOIN tableB”,那么tableA是左边的表,tableB是右边的表。

在ansi标准SQL中定义了五种主要类型的连接:内部连接,这是最常见的;左外接;右外接;全外联接;交叉连接,也称为笛卡尔连接。

内连接

标准SQL上的JOIN查询将产生所谓的内部连接。只有当连接查询中的两个表都匹配时,才会提供结果。例如,如果我们在示例数据上使用这个查询:

从员工的内部连接部门选择*。DeptID == department.DeptID;

查询结果将与示例中的原始电子表格类似:

未定义的

雇员表中有一些记录与部门表没有关系,反之亦然。这些记录不会出现在查询结果中。

内部连接是最常见的连接类型。它是连接的默认类型,所以如果你要写下面的查询:

从员工的内部连接部门选择*。DeptID == department.DeptID;

你会得到同样的结果。

左外连接

左外连接将以与上面相同的方式组合表中的行。这里的不同之处在于,它还将包括来自左表的所有数据,即使与右表没有对应关系。

查询的语法非常相似:

从员工左边选择*,加入员工的部门。DeptID == department.DeptID;

然而,现在有一些额外的行返回不包含任何部门数据:

未定义的

当查询的焦点在左表上,而右表上的数据可能存在,也可能不存在时,左连接非常有用。

右外连接

右外连接的工作方式与左连接相同,不同的是它们包含了来自右表的所有结果。惯例是将主表放在左边,但开发人员可以在方便的地方自由使用右连接。

如上所述,语法只需要join类型的说明:

从员工右边选择*,加入员工的部门。DeptID == department.DeptID;

结果包括右边表中的所有内容,即使左边没有相应的条目。

未定义的

注意,尽管这个右连接的焦点是在部门表上,但它为每个部门返回多个结果。外部连接查询返回由查询产生的所有逻辑行,以及与其他表没有关系的任何剩余行。

完全外部连接

完整的外部连接返回两个表中的所有行。如果行之间存在关系,则连接将它们组合起来。如果不是,它将在需要的地方返回带有NULL值的结果。

查询语法如下所示:

从雇员中选择*完全加入雇员的部门。DeptID == department.DeptID;

如果我们对样本数据执行这个查询,结果如下所示:

未定义的

这两个表中的所有数据值都显示在这些结果中。

交叉连接

交叉连接或笛卡儿连接将左表中的每一行与右表中的每一行合并。

考虑以下示例数据:

未定义的

我们可以用下面的查询显式地创建一个笛卡尔连接:

SELECT * FROM table_A;

或者含蓄地像这样:

SELECT * FROM table_A, table_B;

这个笛卡尔连接的结果将包括所有可能的行组合,看起来像这样:

未定义的

在实践中,这相当于一个没有WHERE条件的内连接。

SQL还允许其他类型的连接,例如自连接和自然连接。您可以通过JOIN和UNION语句的组合来实现这些功能。

术语汇编

数据集成技术的命名指南。

Baidu
map