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

JOIN 三个或更多表

In Module 3 you joined two tables. In the real world data is almost always scattered across three or more tables linked by foreign keys: to answer a business question you have to traverse the chain of relationships. That's exactly what a multi-table JOIN does.

From this module on we'll use the ecommerce dataset (customers, categories, products, orders, order items, reviews). You can explore it from the Playground by selecting ecommerce from the dataset picker.

The syntax: a chain of JOINs

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 …]
…;

Each JOIN adds a "link" to the chain: the engine takes the intermediate result of the previous JOINs and attaches the next table to it.

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;

Three JOINs, four tables. The result has one row per order_items — each product in each order — enriched with customer email and product name.

The logical order

The engine joins tables from left to right. A JOIN condition can reference any table already introduced above. For readability:

  • put the "main table" of the question first (here orders);
  • add the others in the order in which you visit them by following the relationships.

Aggregates over JOIN chains

Multi JOINs combine with GROUP BY to produce reports:

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;

You don't need JOIN products here: everything you need (quantity, unit_price) is already in order_items. Rule of thumb: don't add tables you don't use — they hurt performance and readability.

Try it yourself

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

Per ogni riga d'ordine degli ordini consegnati (status = 'delivered'), mostra email del cliente, nome del prodotto e quantità. Tre colonne. Ordina per id ordine crescente e id prodotto crescente.

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

Three JOINs: orders→customers on customer_id, orders→order_items on order_id, order_items→products on product_id.

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

Review exercise

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

Top 3 clienti per spesa totale (somma di quantity * unit_price) sui soli ordini consegnati. Due colonne: email e total. Ordina per total decrescente, limita a 3.

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

Non ti serve JOIN products: quantity e unit_price sono già in order_items.

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