MySQL 性能:SQL 中的 JOIN 介绍

在本文中,我们将学习在 SQL 中连接表的基础知识。 我们将了解 Left、Right、Inner 和 Outer JOIN 并给出如何使用它们的示例。

RDBMS(关系数据库管理系统)中的数据被分组到表中。 这些表对可以存储在其中的数据类型有严格的定义。 为了连接不同的表,从而连接可能相互关联的不同类型的数据,我们将使用 JOIN 子句。

JOIN 的类型

JOIN 有四种基本类型:INNER、OUTER、LEFT 和 RIGHT。 连接两个表时,它们将根据 ON 子句中的条件分别返回相应表的不同子集。

  • LEFT 和 RIGHT JOIN 执行类似的任务。 它们都返回包含与第二个表相关的信息的单个表的全部内容。
  • INNER 和 OUTER JOIN 执行非常不同的任务。 INNER JOIN 产生的结果非常有限,而 OUTER 返回完整的数据集。

注意:在撰写本文时,MariaDB 和 MySQL 不支持 OUTER JOIN。 然而,我们将提供一个以不同方式产生此输出的方法示例。

在本示例中,我们将在本教程中使用销售部门的示例,使用三个表:销售人员、订单和客户。

销售人员表将包含三列:id、姓名和佣金率。

销售员表

接下来,订单表将包含四列:订单 ID、订单总成本、客户以及销售人员(如果有)。

订单表

客户表将包含两列:id 和基本联系信息。

客户表12-19客户表

所以,我们现在有多个信息表,以不同的方式对不同的人有用。 使用这三个表(销售人员、订单和客户),我们将提供每个 JOIN 可能如何有用的示例。

左加入

可能最常用的 JOIN 类型是 LEFT JOIN。 如果您想到要连接的两个表,则 FROM 子句中提到的那个在左侧。 JOIN 子句中提到的那个在右边。 在 LEFT JOIN 中,LEFT(或 FROM)表中的每一行都在结果中返回,并与 RIGHT(或 JOIN)表中与 ON 子句匹配的相应行链接。

请记住,左侧的某些行可能没有右侧的匹配数据。 在这种情况下,将从结果中的 RIGHT 表填充的字段将由 NULL 值填充。

此外,如果 RIGHT 表中的多行与 LEFT 表中的行匹配,则结果集中将包含多行。 维恩图显示了 LEFT JOIN 的可视化效果:

left-join-12-19左连接示例

营销总监要求您提供按客户细分的所有订单的报告。 您可以为此使用 LEFT JOIN:

SELECT * FROM orders LEFT JOIN customer ON orders.customer_id = customer.id;

该查询查询与“customer”表中的行链接的“orders”表中的所有数据,其中customer的id按顺序等于customer_id。 结果如下所示:

订单表2-12-19

请注意,对于 Widgets LLC 客户,有三个条目,因为他们有三个订单。 Jolly Inc. 下了两个订单,Acme Inc. 下了一个订单。 由于未下订单,因此cheapo 未出现在此列表中。

右加入

RIGHT JOIN 与 LEFT JOIN 非常相似,不同之处在于它返回 RIGHT (JOIN) 表中的每一行,并且只返回 LEFT (FROM) 表中的相应行。 同样,如果 LEFT 表中没有数据,那么这些列将填充为 NULL 值。

如果LEFT表中有多行,那么结果集中就会有多行。 它的维恩图如下所示:

右加入 12-19右连接的一个例子

如果管理层想要与每个客户一起报告; 即使他们没有下订单,我们也可以使用 RIGHT JOIN。

SELECT * FROM orders RIGHT JOIN customer ON orders.customer_id = customer.id;

我们再次从“订单”表开始并将其加入到客户表中。 因为我们使用了 RIGHT JOIN,我们将为 RIGHT (JOIN) 表中的每个条目至少获得一行,customer。 当 customer.id 和 orders.customer_id 匹配时,则填写信息。 结果包括在订单列中为 NULL 值的cheapo Co:

右连接表-12-19

内部联接

INNER JOIN 仅返回与 ON 子句匹配的每一列中的行。 如果右侧没有匹配项,则排除左侧的行,反之亦然。 INNER JOIN 的维恩图如下所示:

内连接12-19INNER JOIN 的一个例子

今天是发薪日,工资部门需要知道要支付多少佣金。 为此,他们需要知道通过每个销售人员下的订单。 请注意,并非所有订单都经过销售人员,因此我们不关心这些。 为此,我们可以使用 INNER JOIN:

SELECT *,cost * commission_rate / 100 AS commission_amount FROM orders INNER JOIN salespeople ON orders.salesperson_id = salespeople.id;

我们再次从订单表开始。 这次我们将它与 salespeople 表连接起来。 如果订单表中的条目与销售人员表中的条目匹配,则该行将被包括在内。 结果中将忽略这些行,而不是用 NULL 值填充不匹配的行。

请注意,我们告诉数据库不仅要返回销售额和佣金率,还要返回计算的佣金。 结果如下所示:

外连接0-12-19

外连接

无论是否匹配,外部连接都会返回所有内容。 如果您要组合 LEFT 和 RIGHT JOIN 的结果,您将获得 OUTER JOIN。 OUTER JOIN 的维恩图如下所示:

外连接 12-19使用 OUTER JOIN 的示例

现在是月底,销售经理想知道所有的销售额以及支付的所有佣金。 为此,我们将使用 OUTER JOIN:

SELECT *,cost * commission_rate / 100 AS commission_amount FROM orders FULL OUTER JOIN salespeople ON orders.salesperson_id = salespeople.id;

与工资单报告一样,我们从订单开始,然后加入销售人员。 不同之处在于,使用 OUTER JOIN,您将从 LEFT 和 RIGHT 表中获得结果,在没有相应匹配的地方填充 NULL。 结果如下所示:

外连接3-12-19

现在,请记住我们说过 MariaDB 和 MySQL 不支持 OUTER JOIN。 我们还说过,如果您将 LEFT JOIN 添加到 RIGHT JOIN,您将获得 OUTER JOIN。 这两个系统的诀窍就是这样做。 我们使用 UNION 子句来实现这一点。 它将一个查询的结果添加到另一个:

SELECT *,cost * commission_rate / 100 AS commission_amount FROM orders LEFT JOIN salespeople ON orders.salesperson_id = salespeople.id UNION SELECT *,cost * commission_rate / 100 AS commission_amount FROM orders RIGHT JOIN salespeople ON orders.salesperson_id = salespeople.id;

结果如下所示:

外连接4-12-19

多重连接

JOIN 还允许您连接两个以上的表。 如果我们想要一份包含客户和销售人员信息的完整销售报告,我们只需在最后再做一次 JOIN。

SELECT * FROM orders LEFT JOIN salespeople ON orders.salesperson_id = salespeople.id LEFT JOIN customer ON customer.id = orders.customer_id;

在这个例子中,我们从 orders 表开始,像之前一样将它连接到 salespeople 表。 下一步是将表加入到客户表中。 这将填写可链接到订单表的所有信息。

多连接-12-19

这篇文章是一个简短的介绍,并不是要详尽讨论如何在 SQL 中使用 JOIN。

点击下方立即使用这个方便的优惠券!

Liquid Web 拥有一些业内最强大的数据库服务器。 这些服务器可用于为企业级公司运行最小的家庭业务到最大的多数据库集群。

给我们打电话 800.580.4985,或打开一个 聊天 或与我们联系,与我们经验丰富的解决方案或托管顾问之一交谈,以了解您今天如何利用这些技术!