back to top

Le join in MySQL: INNER JOIN, LEFT JOIN e RIGHT JOIN

Come abbiamo detto nella prima lezione di questa nostra guida, una delle caratteristiche principali dei database relazionali è quella di poter sfruttare, appunto, le relazioni tra le diverse tabelle del database.

All’interno di MySQL, così come negli altri database di tipo relazionale, le tabelle di un database possono instaurare delle relazioni tra di loro al fine di creare un unicum ed ottenere, con un’unica SELECT informazioni presenti in più tabelle.

Facciamo un esempio. Poniamo di avere a che fare con un database di un ipotetico negozio on-line; supponiamo altresì che questo contenga due sole tabelle (clienti, acquisti) così strutturate:

  • clienti – id, nome, cognome
  • acquisti – id, id_cliente, articolo, prezzo

Ora poniamo di voler recuperare nome e cognome dei soli clienti che hanno effettuato un acquisto. Come fare? Una prima soluzione potrebbe essere quella di effettuare una selezione su due tabelle:

SELECT clienti.*, acquisti.*
FROM clienti, acquisti
WHERE acquisti.id_cliente = clienti.id;

Così facendo abbiamo messo in relazione i record della tabella "clienti" con quelli della tabella "acquisti" mediante la calusola WHERE stabilendo un uguaglianza tra i campo "id_cliente" della tabella "acquisti" ed il campo "id" della tabella "clienti".

Tuttavia avremmo potuto ottenere il medesimo risultato mediante una INNER JOIN, in questo modo:

SELECT clienti.*, acquisti.*
FROM clienti INNER JOIN acquisti
ON acquisti.id_cliente = clienti.id;

Il risultato, come detto, sarebbe stato il medesimo del precedente esempio: questa query, infatti, andrà a selezionare i risultati che hanno una corrispondenza in entrambe le tabelle per i campi specificati.

Le Join

Quello che abbiamo appena visto è un primo esempio di JOIN, ovvero un costrutto del linguaggio SQL attraverso il quale vengono messe in relazione due tabelle. E’ giusto precisare che MySQL supporta tre diversi tipi di JOIN (cross join, inner join e outer join) con finalità differenti.

Le cross join

Sono scarsamente utilizzate nella pratica in quanto offrono il semplice prodotto cartesiano del rapporto tra due tabelle: in pratica, ciascuna riga della prima tabella viene combinata con ciascuna riga della seconda. In pratica se combiniamo due tabelle di 10 righe otterremo un recordset composto da 100 righe (10*10).

Le inner join

Abbiamo già visto questo costrutto: il suo scopo è quello di unire due tabelle restituendo un risultato combinato sulla base di uno o più campi che trovano corrispondenza in tutte le tabelle coinvolte nella JOIN. Valga per questa l’esempio fatto poc’anzi:

SELECT clienti.*, acquisti.* FROM clienti 
INNER JOIN acquisti ON acquisti.id_cliente = clienti.id;

Il collegamento tra le tabelle viene effettuaoa mediante INNER JOIN e la relazione viene stabilita mediante la clausola ON che identifica i campi che, nelle due tabelle, devono offrire l’eguaglianza: verranno estratti, infatti, solo ed esclusivamente i valori che hanno una corrispondenza su tutte le tabelle.

Ovviamente è possibile modificare la query qui sopra ad esempio aggiungendo una clausola WHERE e/o ORDER. Se ad esempio volessimo recuperare i dati dei soli acquisti di valore superiore a 100 Euro ordinandoli da più caro al più economico, avremmo utilizzato una query come questa:

SELECT c.nome, c.cognome FROM clienti AS c 
INNER JOIN acquisti AS a ON a.id_cliente = c.id
WHERE a.prezzo > 100
ORDER BY a.prezzo DESC;

In questo esempio abbiamo utilizzato degli alias per il nome delle tabelle ("c" per la tabella "clienti" e "a" per la tabella "acquisti") al fine di "alleggerire" il codice SQL.

Le outer join

A differenza delle inner join, le outer join selezionano i risultati anche in assenza di una corrispondenza su entrambe le tabelle. Più precisamente è possibile definire in MySQL due tipi di outer join, cioè:

  • LEFT JOIN: estrae tutti i valori della tabella a sinistra anche se non hanno corrispondenza nella tabella a destra;
  • RIGHT JOIN: estrae tutti i valori della tabella a destra anche se non hanno corrispondenza nella tabella di sinistra.

Vediamo un esempio:

SELECT c.nome, c.cognome
FROM clienti AS c
<strong>LEFT JOIN</strong> acquisti AS a ON a.id_cliente = c.id;
WHERE a.prezzo > 100
ORDER BY a.prezzo DESC;

Questa query restituirà tutti i clienti del nostro negozio, compresi quelli che non hanno mai effettuato un acquisto: all’interno del resultset queste righe (quelle prive di duplice corrispondenza) saranno caratterizzate dal valore NULL per tutti i campi pertinenti alla tabella "acquisti".

Il funzionamento di RIGHT JOIN è il medesimo ma, se applicato al nostro esempio, produrrebbe il risultato contrario: cioè quello di mostrare tutti gli acquisti anche se non esiste un utente corrispondente (cosa che, nella pratica, non dovrebbe accadere essendo inconcepibile un acquisto effettuato da "nessun cliente").

Le clausole USING e NATURAL

La sintassi vista sino ad ora può essere abbreviata utilizzando le clausole USING e NATURAL.

La prima clausola (USING) può essere utilizzata quando il campo di JOIN ha lo stesso nome nelle due tabelle messe in relazione. Si supponga, ad esempio, di voler collegare le tabelle "acquisti" e "reclami" sulla base del campo "id_cliente" presente in entrambe:

SELECT ...
FROM acquisti INNER JOIN reclami <strong>USING(id_cliente)</strong>
...

La seconda clausola (NATURAL) può essere utilizzata quando si vuole creare una JOIN utilizzando tutti i campi che hanno lo stesso nome all’interno delle due tabelle collegate:

SELECT ...
FROM acquisti <strong>NATURAL LEFT JOIN</strong> reclami
...

Entrambe queste clausole possono essere utilizzare sia nelle INNER JOIN che nelle OUTER JOIN.

Join tra più tabelle

Abbiamo visto che le JOIN sono utilizzate per creare relazioni fra due tabelle, tuttavia nulla vieta di creare una serie di JOIN in per relazionare una molteplicità di tabelle fra loro. Vediamo un esempio:

SELECT c.nome, c.cognome
FROM clienti AS c
LEFT JOIN acquisti AS a ON a.id_cliente = c.id
LEFT JOIN reclami AS r ON r.id_cliente = c.id;

Come potete vedere abbiamo creato una relazione tra tre tabelle (clienti, acquisti, reclami) mediante due JOIN.

Pubblicitร 
Massimiliano Bossi
Massimiliano Bossi
Stregato dalla rete sin dai tempi delle BBS e dei modem a 2.400 baud, ho avuto la fortuna di poter trasformare la mia passione in un lavoro (nonostante una Laurea in Giurisprudenza). Adoro scrivere codice e mi occupo quotidianamente di comunicazione, design e nuovi media digitali. Orgogliosamente "nerd" sono il fondatore di MRW.it (per il quale ho scritto centinaia di articoli) e di una nota Web-Agency (dove seguo in prima persona progetti digitali per numerosi clienti sia in Italia che all'estero).

In questa guida...