Direct naar de hoofdinhoud
Module 5 · Les 1 van 417/57 in de cursus~12 min
Modulelessen (1/4)

JOIN op drie of meer tafels

In Module 3 heb je aan twee tafels deelgenomen. In de echte wereld zijn gegevens bijna altijd verspreid over drie of meer tabellen die zijn gekoppeld door externe sleutels: to een zakelijke vraag beantwoorden, je moet de keten van relaties doorkruisen. Dat is precies wat een multi-tabel JOIN doet.

Vanaf deze module gebruiken we de dataset ecommerce (klanten, categorieën, producten, bestellingen, bestelartikelen, recensies). Je kunt het verkennen vanuit de Playground door ecommerce uit de dataset te selecteren kiezer.

De syntaxis: een keten van JOIN's

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

Elke JOIN voegt een "schakel" toe aan de keten: de engine neemt het tussenproduct resultaat van de vorige JOIN's en koppelt de volgende tabel eraan.

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;

Drie JOINs, vier tafels. Het resultaat heeft één rij per order_items — elk product in elke bestelling — verrijkt met e-mailadres van de klant en productnaam.

De logische volgorde

De engine voegt tabellen toe van links naar rechts. Een JOIN voorwaarde kan dat wel verwijs naar een tabel die hierboven al is geïntroduceerd. Voor leesbaarheid:

  • plaats eerst de "hoofdtabel" van de vraag (hier orders);
  • voeg de anderen toe in de volgorde waarin u ze bezoekt door de volgende te volgen relaties.

Aggregaten via JOIN-ketens

Meerdere JOINs worden gecombineerd met GROUP BY om rapporten te produceren:

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;

Je hebt hier JOIN products niet nodig: alles wat je nodig hebt (quantity, unit_price) bevindt zich al in order_items. Vuistregel: voeg geen tabellen toe die u niet gebruikt — ze zijn schadelijk voor de prestaties en leesbaarheid.

Probeer het zelf

Oefening#sql.m5.l1.e1
Pogingen: 0Laden…

Voor het bestellen van bestellingen (status = 'afgeleverd'), de meeste e-mail van de klant, de naam van het product en de hoeveelheid. Tre colonne. Ordina voor id ordine crescente en id prodotto crescente.

Editor laden…
Toon hint

Drie JOIN's: bestellingen → klanten op klant_id, bestellingen → order_items op order_id, order_items → producten op product_id.

Oplossing beschikbaar na 3 pogingen

Oefening beoordelen

Oefening#sql.m5.l1.e2
Pogingen: 0Laden…

Top 3 klanten per totaal (somma van hoeveelheid * unit_price) sui soli ordini consegnati. Due colonne: e-mail en totaal. Ordina per totaal decescente, limita a 3.

Editor laden…
Toon hint

Niet serveren JOIN producten: hoeveelheid en eenheidsprijs sono già in order_items.

Oplossing beschikbaar na 3 pogingen