
In questo sesto tutorial della serie dedicata a MySQL da riga di comando, affrontiamo uno dei concetti più potenti dei database relazionali: le JOIN. Fino ad ora, interrogando la tabella degli ordini, ottenevamo solo un numero per identificare l’acquirente (
id_cliente). Oggi impareremo a unire le tabelle clienti e ordini per estrarre report completi e leggibili.1. Comprendere l’INNER JOIN
L’
INNER JOIN è l’unione più comune. Restituisce solo i record che hanno una corrispondenza esatta in entrambe le tabelle collegate tramite la chiave primaria e la chiave esterna.Vogliamo visualizzare il nome e il cognome del cliente accanto all’importo di ogni ordine:
SQL
SELECT clienti.nome, clienti.cognome, ordini.id_ordine, ordini.importo_totale
FROM clienti
INNER JOIN ordini ON clienti.id_cliente = ordini.id_cliente;
Output previsto
+-------+---------+-----------+----------------+
| nome | cognome | id_ordine | importo_totale |
+-------+---------+-----------+----------------+
| Mario | Rossi | 1 | 134.99 |
| Mario | Rossi | 2 | 49.50 |
| Mario | Rossi | 5 | 25.00 |
| Laura | Bianchi | 6 | 150.00 |
| Laura | Bianchi | 7 | 35.50 |
| Elena | Neri | 8 | 80.00 |
+-------+---------+-----------+----------------+
6 rows in set (0.00 sec)
In questo modo, MySQL consulta la tabella
clienti, trova l’utente corrispondente all’id_cliente registrato nell’ordine e stampa la riga combinata.2. Semplificare le Query con gli Alias delle Tabelle
Quando si usano le JOIN, scrivere ripetutamente il nome intero delle tabelle (
clienti.nome, ordini.importo_totale) rende il codice lungo e difficile da leggere nel terminale. Possiamo usare gli Alias per assegnare un’etichetta breve (es. c per clienti, o per ordini).Riscriviamo la stessa query aggiungendo anche un ordinamento:
SQL
SELECT c.nome, c.cognome, o.id_ordine, o.importo_totale
FROM clienti c
INNER JOIN ordini o ON c.id_cliente = o.id_cliente
ORDER BY o.importo_totale DESC;
Output previsto
+-------+---------+-----------+----------------+
| nome | cognome | id_ordine | importo_totale |
+-------+---------+-----------+----------------+
| Laura | Bianchi | 6 | 150.00 |
| Mario | Rossi | 1 | 134.99 |
| Elena | Neri | 8 | 80.00 |
| Mario | Rossi | 2 | 49.50 |
| Laura | Bianchi | 7 | 35.50 |
| Mario | Rossi | 5 | 25.00 |
+-------+---------+-----------+----------------+
6 rows in set (0.00 sec)
3. Creare un Caso d’Uso per la LEFT JOIN
Cosa succede se un cliente si è registrato ma non ha ancora effettuato alcun ordine? L’
INNER JOIN non lo mostrerebbe. Per visualizzare tutti i clienti (la tabella “di sinistra”), inclusi quelli senza ordini, si usa la LEFT JOIN.Per fare un test pratico, inseriamo un nuovo cliente senza ordini:
SQL
INSERT INTO clienti (nome, cognome, email) VALUES ('Paolo', 'Gialli', 'paolo.gialli@esempio.com');
Output previsto
Query OK, 1 row affected (0.01 sec)
Ora eseguiamo la
LEFT JOIN:SQL
SELECT c.nome, c.cognome, o.id_ordine, o.importo_totale
FROM clienti c
LEFT JOIN ordini o ON c.id_cliente = o.id_cliente;
Output previsto
+-------+---------+-----------+----------------+
| nome | cognome | id_ordine | importo_totale |
+-------+---------+-----------+----------------+
| Mario | Rossi | 1 | 134.99 |
| Mario | Rossi | 2 | 49.50 |
| Mario | Rossi | 5 | 25.00 |
| Laura | Bianchi | 6 | 150.00 |
| Laura | Bianchi | 7 | 35.50 |
| Elena | Neri | 8 | 80.00 |
| Paolo | Gialli | NULL | NULL |
+-------+---------+-----------+----------------+
7 rows in set (0.00 sec)
Come puoi vedere, Paolo Gialli appare nella lista, ma i valori relativi alla tabella degli ordini restituiscono
NULL (valore assente), indicando che non ha ancora acquistato nulla.4. Unire le JOIN alle Funzioni di Aggregazione
Possiamo combinare le JOIN studiate oggi con il
GROUP BY visto nel tutorial precedente. Creiamo un report riepilogativo che mostri il totale speso da ogni utente, stampando nome e cognome invece del solo ID numerico:SQL
SELECT c.nome, c.cognome, SUM(o.importo_totale) AS totale_speso
FROM clienti c
INNER JOIN ordini o ON c.id_cliente = o.id_cliente
GROUP BY c.id_cliente;
Output previsto
+-------+---------+--------------+
| nome | cognome | totale_speso |
+-------+---------+--------------+
| Mario | Rossi | 209.49 |
| Laura | Bianchi | 185.50 |
| Elena | Neri | 80.00 |
+-------+---------+--------------+
3 rows in set (0.00 sec)
Nel prossimo Tutorial 7, lasceremo le query di selezione per dedicarci a un’operazione fondamentale per la sicurezza: l’esportazione e il backup del database (mysqldump).
