Salt la conținutul principal
Modulul 5 · Lecția 1 din 417/57 în curs~12 min
Lecții din modul (1/4)

JOIN pe trei sau mai multe mese

În Modulul 3 ați alăturat două mese. În lumea reală, datele sunt aproape întotdeauna împrăștiate în trei sau mai multe tabele legate prin chei străine: to raspunde la o intrebare de afaceri pe care trebuie sa traversezi lantul de relatii. Exact asta face un JOIN cu mai multe mese.

Din acest modul vom folosi setul de date ecommerce (clienți, categorii, produse, comenzi, articole de comandă, recenzii). Îl poți explora de la Playground selectând ecommerce din setul de date culegător.

Sintaxa: un lanț de JOIN-uri

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

Fiecare JOIN adaugă o „verigă” la lanț: motorul ia intermediarul rezultat al JOIN-urilor anterioare și îi atașează următorul tabel.

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;

Trei JOINs, patru mese. Rezultatul are câte un rând pe order_items — fiecare produs în fiecare comandă — îmbogățit cu e-mailul clientului și numele produsului.

Ordinea logica

Motorul unește tabele de la stânga la dreapta. O condiție JOIN poate referiți la orice tabel deja introdus mai sus. Pentru lizibilitate:

  • pune pe primul loc „tabelul principal” al întrebării (aici orders);
  • adăugați-i pe ceilalți în ordinea în care le vizitați urmând relatii.

Agregate prin lanțuri JOIN

JOIN-uri multiple se combină cu GROUP BY pentru a produce rapoarte:

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;

Nu aveți nevoie de JOIN products aici: tot ce aveți nevoie (quantity, unit_price) este deja în order_items. Regula generală: nu adăugați tabele nu folosești — afectează performanța și lizibilitatea.

Încercați-l singur

Exercițiu#sql.m5.l1.e1
Încercări: 0Se încarcă…

Per ogni riga d'ordine degli ordini consegnati (status = „livrat”), afișează e-mailul clientului, nume de produs și cantitate. Tre colonne. Ordina per id ordine crescente e id prodotto crescente.

Se încarcă editorul...
Afișează indiciu

Trei JOIN-uri: comenzi→clienți pe customer_id, orders→order_items pe order_id, order_items→produs pe product_id.

Soluție disponibilă după 3 încercări

Exercițiu de revizuire

Exercițiu#sql.m5.l1.e2
Încercări: 0Se încarcă…

Top 3 clienti per spesa totala (summa de cantitate * unit_price) sui soli ordini consegnati. Due coloane: email e total. Ordina per total decrescente, limita a 3.

Se încarcă editorul...
Afișează indiciu

Nu vă serviți produsele JOIN: cantitatea și prețul_unității sunt deja în articolele_comandă.

Soluție disponibilă după 3 încercări