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.