跳转到主要内容
模块 5 · 第 1 课(共 4)课程中的17/57~12 min
模块课程(1/4)

JOIN 三个或更多表

在模块 3 中,您连接了两个表。在现实世界中数据几乎是 总是分散在由外键链接的三个或更多表中: 回答一个业务问题你必须遍历关系链。 这正是多表 JOIN 的作用。

从本模块开始,我们将使用 ecommerce 数据集(客户、 类别、产品、订单、订单项目、评论)。您可以从以下位置探索它 通过从数据集中选择 ecommerce 来创建 Playground 选择器。

语法:JOIN 链

SQL
SELECT colonne
FROM   tabella_a
JOIN   tabella_b ON tabella_a.x = tabella_b.y
JOIN   tabella_c ON tabella_b.z = tabella_c.w
[JOIN  tabella_d ON …]
…;

每个 JOIN 都会向链中添加一个“链接”:引擎采用中间 先前 JOIN 的结果并将下一个表附加到它。

SQL
-- Per ogni riga d'ordine: cliente, prodotto e quantità.
SELECT c.email,
       p.name AS prodotto,
       oi.quantity
FROM   orders      AS o
JOIN   customers   AS c  ON o.customer_id = c.id
JOIN   order_items AS oi ON oi.order_id   = o.id
JOIN   products    AS p  ON oi.product_id = p.id;

三个 JOIN,四个表。结果每 order_items 一行 — 每个 每个订单中的产品 - 包含客户电子邮件和产品名称。

逻辑顺序

引擎从左到右连接表。 JOIN 条件可以 参考上面已经介绍过的任何表格。为了便于阅读:

  • 将问题的“主表”放在第一位(此处为orders);
  • 按照您访问的顺序添加其他内容 关系。

JOIN 链上的聚合

多个 JOIN 与 GROUP BY 结合生成报告:

SQL
-- Spesa totale per cliente (solo ordini consegnati):
SELECT c.email,
       SUM(oi.quantity * oi.unit_price) AS total
FROM   customers   AS c
JOIN   orders      AS o  ON o.customer_id = c.id
JOIN   order_items AS oi ON oi.order_id   = o.id
WHERE  o.status = 'delivered'
GROUP BY c.email
ORDER BY total DESC;

您在这里不需要 JOIN products:您需要的一切(quantity, unit_price) 已位于 order_items 中。经验法则:不要添加表 你不使用——它们会损害性能和可读性。

自己尝试一下

锻炼#sql.m5.l1.e1
尝试:0加载中...

Per ogni riga d'ordine degli ordini consegnati(状态=“已交付”),请通过电子邮件向客户发送,名称为产品和数量。特雷科隆。 Ordina per id ordine crescente 和 id prodotto crescente。

正在加载编辑器...
显示提示

三个 JOIN:订单→customer_id 上的客户、order_id 上的订单→order_items、order_items→product_id 上的产品。

3 次尝试后可用的解决方案

复习练习

锻炼#sql.m5.l1.e2
尝试:0加载中...

每个 spesa 总计前 3 位客户(数量 * 单价) sui soli ordini consegnati。截止日期:电子邮件 e 总计。 Ordina 每总递减,限制 a 3。

正在加载编辑器...
显示提示

不可提供 JOIN 产品:数量和单价在订单项目中。

3 次尝试后可用的解决方案