f in x
JOIN SQL: INNER, LEFT, RIGHT, FULL, CROSS e Self Join con esempi pratici
> cd .. / HUB_EDITORIALE > Visualizza in Inglese
Analisi dei dati e metriche

JOIN SQL: INNER, LEFT, RIGHT, FULL, CROSS e Self Join con esempi pratici

[2026-06-04] Author: Ing. Calogero Bono

Hai due tabelle con dati collegati e non sai come estrarre solo le righe che corrispondono? Oppure vuoi vedere anche i clienti che non hanno mai ordinato, o magari devi confrontare una tabella con se stessa? I JOIN SQL sono il cuore delle query relazionali. Chi ha detto che i dati sono noiosi? No, sono il carburante delle decisioni aziendali. Noi di Meteora Web ci siamo passati ogni giorno: gestire il magazzino di un negozio, incrociare ordini e fatture, capire chi compra e chi no. Senza JOIN, quei numeri sarebbero solo liste separate. Con i JOIN, diventano informazioni utili per vendere di più, sprecare meno e capire il tuo business davvero.

Perché i JOIN sono indispensabili

Un database relazionale è fatto di tante piccole tabelle collegate da chiavi (primary e foreign key). Per ottenere un report completo devi unirle. È come avere i registri contabili separati: clienti su un foglio, fatture su un altro. Senza unire, non sai se un cliente ha pagato o se ha ordini in sospeso. I JOIN ti permettono di:

  • Combinare righe di due o più tabelle basandoti su una condizione (di solito uguaglianza di chiavi).
  • Filtrare i dati combinati con WHERE e raggrupparli con GROUP BY.
  • Decidere se includere solo le corrispondenze o anche i dati di una tabella che non hanno match.

Quando parliamo con i nostri clienti, spieghiamo sempre che i JOIN sono il modo per rispondere a domande concrete: "quanti clienti non hanno mai acquistato?", "qual è il prodotto più venduto in ogni categoria?", "quanto fattura un fornitore specifico?". Senza JOIN, dovresti fare più query manuali o, peggio, unire tutto in Excel — con tutti i rischi di errori.

Come funziona un JOIN: il principio della condizione

Immagina di avere due tabelle: clienti (id, nome, email) e ordini (id, cliente_id, data, importo). La connessione è cliente_id = clienti.id. Un JOIN confronta ogni riga di una tabella con ogni riga dell'altra secondo la condizione. Se la condizione è vera, le righe vengono accorpate in una riga unica. Il tipo di JOIN decide cosa fare con le righe che non soddisfano la condizione.

Noi di Meteora Web, venendo anche dalla contabilità, lo vediamo come una partita doppia tra due libri mastrino: ogni movimento in un libro ha una contropartita nell'altro. Il JOIN ti dice se la quadratura è perfetta o se ci sono sospesi.

INNER JOIN: solo le corrispondenze

L'INNER JOIN restituisce solo le righe che hanno una corrispondenza in entrambe le tabelle. Se un cliente non ha ordini, non appare nel risultato. È il JOIN più comune per estrarre dati correlati.

Esempio pratico: clienti con ordini

SELECT clienti.nome, ordini.data, ordini.importo
FROM clienti
INNER JOIN ordini ON clienti.id = ordini.cliente_id;

Questo restituisce solo i clienti che hanno almeno un ordine. Se hai 100 clienti ma solo 30 hanno ordinato, ottieni 30 righe (uno per ordine, quindi anche più righe se un cliente ha più ordini).

In sintesi per il business: "Quali clienti hanno acquistato?" — INNER JOIN ti dà la lista di chi ha comprato almeno una volta.

LEFT JOIN (LEFT OUTER JOIN): tutto da sinistra, match da destra

Il LEFT JOIN restituisce tutte le righe della tabella di sinistra (quella dopo FROM) e, per ciascuna, le righe corrispondenti della tabella di destra. Se non c'è corrispondenza, i campi di destra sono NULL. È utilissimo per trovare "cose che mancano".

Esempio pratico: clienti con o senza ordini

SELECT clienti.nome, ordini.data, ordini.importo
FROM clienti
LEFT JOIN ordini ON clienti.id = ordini.cliente_id;

Ora ottieni tutti i clienti, anche quelli senza ordini. Per quelli senza ordini, data e importo saranno NULL. Per trovare solo i clienti che non hanno mai ordinato, aggiungi un filtro:

SELECT clienti.nome
FROM clienti
LEFT JOIN ordini ON clienti.id = ordini.cliente_id
WHERE ordini.id IS NULL;

Perché conviene? Noi lo usiamo per identificare clienti inattivi da coinvolgere con campagne marketing. Un cliente che non ha mai ordinato è un'opportunità persa. Con LEFT JOIN + WHERE IS NULL lo trovi in un secondo.

RIGHT JOIN (RIGHT OUTER JOIN): tutto da destra, match da sinistra

È l'opposto del LEFT JOIN. Restituisce tutte le righe della tabella di destra e, per ciascuna, le corrispondenze di sinistra. In pratica si può sempre riscrivere come LEFT JOIN scambiando l'ordine delle tabelle. Noi consigliamo di usare quasi sempre LEFT JOIN per chiarezza, ma RIGHT JOIN esiste e a volte semplifica il codice se la logica mentale è "da questa tabella voglio tutto".

Esempio pratico: ordini anche senza cliente (dati sporchi)

SELECT clienti.nome, ordini.data, ordini.importo
FROM clienti
RIGHT JOIN ordini ON clienti.id = ordini.cliente_id;

Restituisce tutti gli ordini, anche quelli con cliente_id nullo o inesistente. Nella pratica, noi lo usiamo raramente: preferiamo LEFT JOIN e scambiare l'ordine delle tabelle. Ma se devi controllare l'integrità referenziale di una tabella, RIGHT JOIN può essere veloce.

FULL JOIN (FULL OUTER JOIN): tutto da entrambe le parti

Il FULL JOIN restituisce tutte le righe di entrambe le tabelle. Quando c'è corrispondenza, le righe sono unite; quando non c'è, i campi dell'altra tabella sono NULL. È il JOIN più completo ma anche il più pesante. Lo usi quando vuoi un elenco completo di tutte le entità coinvolte, indipendentemente dal fatto che abbiano relazioni.

Esempio pratico: tutti i clienti e tutti gli ordini in un unico report

SELECT clienti.nome, ordini.data, ordini.importo
FROM clienti
FULL JOIN ordini ON clienti.id = ordini.cliente_id;

Restituisce:

  • Clienti con ordini (uniti)
  • Clienti senza ordini (campi ordini NULL)
  • Ordini senza clienti (campi clienti NULL)

Attenzione: MySQL non supporta FULL JOIN nativamente in tutte le versioni (puoi simulare con UNION di LEFT e RIGHT). PostgreSQL e SQL Server lo supportano. Noi di Meteora Web, quando lavoriamo con MySQL, usiamo la simulazione:

SELECT clienti.nome, ordini.data, ordini.importo
FROM clienti
LEFT JOIN ordini ON clienti.id = ordini.cliente_id
UNION
SELECT clienti.nome, ordini.data, ordini.importo
FROM clienti
RIGHT JOIN ordini ON clienti.id = ordini.cliente_id
WHERE clienti.id IS NULL;

CROSS JOIN: prodotto cartesiano

Il CROSS JOIN restituisce ogni combinazione possibile tra le righe di due tabelle. Non c'è condizione di join. Se tabella A ha 10 righe e tabella B ha 20 righe, il risultato ha 200 righe. È pericoloso se usato per errore: una volta un cliente ci ha chiamato perché la query non finiva mai. Era un CROSS JOIN su tabelle con milioni di righe.

Esempio pratico: generare tutte le combinazioni di prodotti e colori

SELECT prodotti.nome, colori.colore
FROM prodotti
CROSS JOIN colori;

Quando usarlo: per creare matrici di dati, calendari, o per generare tutte le possibili varianti di un prodotto. Ma sempre con tabelle piccole o con un WHERE che riduce.

Self JOIN: unisci una tabella con se stessa

Il self JOIN è quando usi la stessa tabella più volte nella stessa query, dandole alias diversi. Serve per confrontare righe all'interno della stessa tabella. Ad esempio, trovare impiegati e il loro manager (se la colonna manager_id punta allo stesso id nella tabella impiegati).

Esempio pratico: impiegati e capi

SELECT e1.nome AS impiegato, e2.nome AS capo
FROM impiegati e1
LEFT JOIN impiegati e2 ON e1.manager_id = e2.id;

Usiamo LEFT JOIN per includere anche chi non ha capo (es. CEO). Altro esempio: trovare prodotti duplicati basati sul nome:

SELECT p1.id, p1.nome, p2.id
FROM prodotti p1
INNER JOIN prodotti p2 ON p1.nome = p2.nome AND p1.id < p2.id;

Perché serve? Noi lo abbiamo usato per analizzare l'inventario: trovare fornitori che vendono lo stesso prodotto a prezzi diversi, o clienti che hanno acquistato lo stesso articolo in date diverse.

Errori comuni (e come evitarli)

  • Dimenticare la condizione in JOIN: Se scrivi FROM a JOIN b senza ON, ottieni un CROSS JOIN involontario (a meno che non usi sintassi vecchia con WHERE implicita). Sempre specificare ON.
  • Confondere LEFT e RIGHT: Noi scriviamo sempre la tabella da cui vogliamo TUTTI i dati a sinistra. Se ti confondi, parti dal LEFT e scambia l'ordine.
  • Non usare alias: Quando hai più tabelle con colonne omonime (es. id), usa alias di tabella o prefissi. Es: c.nome AS cliente, o.id AS ordine.
  • FULL JOIN senza bisogno: Di solito ti serve solo LEFT + eventuale filtro per trovare ciò che manca. Il FULL JOIN è utile solo se devi analizzare entrambi i lati delle mancanze.
  • Self JOIN senza alias: Obbligatorio dare alias diversi (es. e1, e2). Senza, il database non sa distinguere le due istanze della stessa tabella.

Performance: attenzione ai JOIN multipli

Ogni JOIN aggiunge complessità. Su tabelle grandi (milioni di righe), un JOIN senza indice sulla colonna usata nella condizione diventa un'operazione sequenziale lentissima. Noi di Meteora Web verifichiamo sempre gli indici con EXPLAIN prima di mettere in produzione query complesse. Un LEFT JOIN su una colonna indicizzata è veloce; su una colonna non indicizzata, il database dovrà confrontare ogni riga.

Consiglio pratico: crea indici sulle foreign key e su tutte le colonne usate nelle clausole ON e WHERE. Esempio: CREATE INDEX idx_ordini_cliente ON ordini(cliente_id);

In sintesi — cosa fare

  • INNER JOIN: quando vuoi solo dati che esistono in entrambe le tabelle.
  • LEFT JOIN: quando vuoi tutti i dati di una tabella (sinistra) e, se ci sono, quelli dell'altra.
  • RIGHT JOIN: come LEFT ma con la tabella di destra che comanda. Meglio evitare se possibile.
  • FULL JOIN: quando vuoi tutto da entrambi i lati, anche gli orfani. Usa con cautela.
  • CROSS JOIN: solo per combinazioni forzate. Verifica sempre le dimensioni.
  • Self JOIN: per confrontare righe dentro la stessa tabella.

Ora apri il tuo database e prova a scrivere una query con LEFT JOIN tra clienti e ordini. Poi aggiungi WHERE ordini.id IS NULL e scopri chi non ha mai comprato. È il primo passo per trasformare dati grezzi in decisioni concrete.

Sponsored Protocol

Ing. Calogero Bono

> AUTHOR_EXTRACTED

Ing. Calogero Bono

Co-founder di Meteora Web. Ingegnere informatico, sviluppo ecosistemi digitali ad alte prestazioni. AI, automazione, SEO tecnica e infrastrutture web. Scrivo di tecnologia per rendere complesso… semplice.

[ Read Full Dossier ]

Hai bisogno di applicare questa strategia?

Esegui il protocollo di contatto per iniziare un progetto con noi.

> INIZIA_PROGETTO

Sponsored

> MW_JOURNAL

> READ_ALL()