Torna all'elenco degli articoli Articoli
Tempo di lettura: 10 minuti

Spiegazione dei tipi di JOIN in SQL

Qual è la differenza tra INNER JOIN, LEFT JOIN, RIGHT JOIN e FULL JOIN in SQL? Quando è opportuno utilizzarle? Abbiamo qui le risposte.

Volete combinare i dati di due o più tabelle diverse, ma non siete sicuri di come farlo in SQL. Non preoccupatevi. In questo articolo vi mostrerò come utilizzare la clausola SQL JOIN per unire i dati di due tabelle. Esistono diversi tipi di SQL JOIN che possono essere utilizzati per ottenere risultati diversi. Se volete conoscere le differenze tra INNER JOIN, LEFT JOIN, RIGHT JOIN e FULL JOIN, continuate a leggere. Questo articolo fa al caso vostro.

Innanzitutto, cominciamo dalle basi: cos'è un'istruzione JOIN e come funziona?

Che cos'è una JOIN SQL?

La clausola JOIN viene utilizzata quando è necessario combinare i dati di due o più tabelle in un unico insieme di dati. I record di entrambe le tabelle vengono abbinati in base a una condizione (detta anche predicato JOIN ) specificata nella clausola JOIN. Se la condizione è soddisfatta, i record vengono inclusi nell'output.

In questo articolo spiegherò il concetto di SQL JOIN e i diversi tipi di JOIN utilizzando degli esempi. Quindi, prima di proseguire, diamo un'occhiata alle tabelle che utilizzeremo in questo articolo.

Conoscere il database

Utilizzeremo le tabelle di un database bancario immaginario. La prima tabella è called e contiene i dati relativi ai conti bancari dei clienti:

account_idoverdraft_amtcustomer_idtype_idsegment
25568891200042RET
1323598795155011RET
2225546500052RET
5516229600045RET
5356222750055RET
2221889540012RET
245568812500502CORP
13224886562500511CORP
13235987953100521CORP
13231115951220531CORP

tabella dei conti

Questa tabella contiene 10 record (10 conti) e cinque colonne:

  • account_id - Identifica in modo univoco ogni conto.
  • overdraft_amount - Il limite di scoperto per ogni conto.
  • customer_id - Identifica in modo univoco ogni cliente.
  • type_id - Identifica il tipo di conto.
  • segment - Contiene i valori "RET" (per i clienti al dettaglio) e "CORP" (per i clienti aziendali).

La seconda tabella si chiama customer e contiene dati relativi ai clienti:

customer_idnamelastnamegendermarital_status
1MARCTESCOMY
2ANNAMARTINFN
3EMMAJOHNSONFY
4DARIOPENTALMN
5ELENASIMSONFN
6TIMROBITHMN
7MILAMORRISFN
8JENNYDWARTHFY

tabella clienti

Questa tabella contiene otto record e cinque colonne:

  • customer_id - Identifica in modo univoco ogni conto.
  • name - Nome del cliente.
  • lastname - Il cognome del cliente.
  • gender- Il sesso del cliente (M o F).
  • marital_status - Se il cliente è sposato (Y o N).

Ora che disponiamo di queste due tabelle, possiamo combinarle per visualizzare ulteriori risultati relativi ai dati dei clienti o dei conti. JOIN può aiutarci a ottenere risposte a domande come:

  • Chi possiede ogni conto nella tabella account tabella?
  • Quanti conti ha Marc Tesco?
  • Quanti conti possiede una cliente donna?
  • Qual è l'importo totale dello scoperto per tutti i conti di Emma Johnson?

Per rispondere a ciascuna di queste domande, dobbiamo combinare due tabelle (account e customer) utilizzando una colonna presente in entrambe le tabelle (in questo caso, customer_id). Una volta unite le due tabelle, avremo le informazioni sul conto e sul cliente in un unico output.

Si tenga presente che nella tabella account abbiamo alcuni clienti che non si trovano nella tabella customer tabella. (Le informazioni sui clienti aziendali sono memorizzate da qualche altra parte). Inoltre, si tenga presente che alcuni ID cliente non sono presenti nella tabella. account tabella; alcuni clienti non hanno un conto.

Esistono diversi modi per combinare due tabelle. O, in altri termini, possiamo dire che esistono diversi tipi di SQL JOIN.

I 4 tipi di JOIN di SQL

I tipi di SQL JOIN includono:

  • INNER JOIN (nota anche come "semplice" JOIN). È il tipo di JOIN più comune.
  • LEFT JOIN (o LEFT OUTER JOIN)
  • RIGHT JOIN (o RIGHT OUTER JOIN)
  • FULL JOIN (o FULL OUTER JOIN)
  • In SQL sono possibili anche self join e cross join, ma non ne parleremo in questo articolo. Per maggiori informazioni, consultate una Guida illustrata alle Self Join e una Guida illustrata alle Cross Join in SQL.

Approfondiamo i primi quattro tipi di SQL JOIN. Utilizzerò un esempio per spiegare la logica e la sintassi di ciascun tipo. A volte si usano i diagrammi di Venn per spiegare i tipi di JOIN SQL. Non li userò in questa sede, ma se è la vostra passione, date un'occhiata all'articolo Come imparare SQL JOINs.

LA CONGIUNZIONE INTERNA

INNER JOIN si usa per visualizzare i record corrispondenti di entrambe le tabelle. Si tratta anche di una semplice JOIN; se si omette la parola chiave INNER (o qualsiasi altra parola chiave, come LEFT, RIGHT o FULL) e si usa solo JOIN, questo è il tipo di join che si ottiene di default.

Di solito ci sono due (o più) tabelle in una dichiarazione di join. Le chiamiamo tabelle di destra e di sinistra. La tabella di sinistra si trova nella clausola FROM e quindi a sinistra della parola chiave JOIN. La tabella di destra si trova tra le parole chiave JOIN e ON, o a destra della parola chiave JOIN.

Se la condizione JOIN è soddisfatta in una INNER JOIN, quel record è incluso nell'insieme di dati. Può provenire da entrambe le tabelle. Se il record non corrisponde ai criteri, non viene incluso. L'immagine seguente mostra cosa accadrebbe se il colore blu fosse il criterio di unione per le tabelle di destra e di sinistra:

GIUNZIONE INTERNA

Vediamo come funziona INNER JOIN nel nostro esempio. Eseguirò un semplice JOIN su account e cliente per visualizzare account e customer informazioni in un unico output:

SELECT account.*,
      customer.name,
      customer.lastname,
      customer.gender,
      customer.marital_status
FROM account 
JOIN customer 
ON account.customer_id=customer.customer_id;

Ecco una breve spiegazione di ciò che sta accadendo:

  • Sto usando JOIN perché stiamo unendo gli attributi account e customer e le tabelle.
  • Il predicato JOIN è definito dall'uguaglianza:

account.customer_id = customer.customer_id

In altre parole, i record vengono abbinati in base ai valori della colonna customer_id:

CONGIUNGERE
  • I record che condividono lo stesso valore di ID cliente vengono abbinati. (I record che non hanno una corrispondenza in nessuna delle due tabelle (in grigio) non vengono inclusi nel set di risultati.
  • Per i record che hanno una corrispondenza, tutti gli attributi della tabella account vengono visualizzati nel set di risultati. Vengono visualizzati anche gli attributi nome, cognome, sesso e stato civile della tabella customer della tabella.

Dopo aver eseguito questo codice, SQL restituisce il seguente risultato:

account_idoverdraft_amountcustomer_idtype_idsegmentnamelastnamegendermarital_status
25568891200042RETDARIOPENTALMN
1323598795155011RETMARCTESCOMY
2225546500052RETELENASIMSONFN
5516229600045RETDARIOPENTALMN
5356222750055RETELENASIMSONFN
2221889540012RETMARCTESCOMY

INNER JOIN risultato

Come abbiamo detto prima, sono stati restituiti solo i record colorati (corrispondenti); tutti gli altri sono stati scartati. In termini commerciali, abbiamo visualizzato tutti i conti al dettaglio con informazioni dettagliate sui loro proprietari. I conti non al dettaglio non sono stati visualizzati perché le loro informazioni sui clienti non sono memorizzate nella tabella. customer tabella.

SINISTRA

A volte è necessario mantenere tutti i record della tabella di sinistra, anche se alcuni non hanno una corrispondenza nella tabella di destra. Nell'ultimo esempio, le righe grigie non sono state visualizzate nell'output. Si tratta di conti aziendali. In alcuni casi, si potrebbe desiderare di averli nel set di dati, anche se i dati dei clienti sono lasciati vuoti. Se si desidera restituire i record non abbinati dalla tabella di sinistra, si deve scrivere una LEFT JOIN. Di seguito, si può vedere che la LEFT JOIN restituisce tutto ciò che è presente nella tabella di sinistra e le righe corrispondenti nella tabella di destra.

GIUNTA SINISTRA

Ecco come apparirebbe la query precedente se usassimo LEFT JOIN invece di INNER JOIN:

SELECT account.*,
      customer.name,
      customer.lastname,
      customer.gender,
      customer.marital_status
FROM account 
LEFT JOIN customer 
ON account.customer_id=customer.customer_id;

La sintassi è identica. Il risultato, tuttavia, non è lo stesso. Ora possiamo vedere i conti aziendali (record grigi) nei risultati:

account_idoverdraft_amountcustomer_idtype_idsegmentnamelastnamegendermarital_status
25568891200042RETDARIOPENTALMN
1323598795155011RETMARCTESCOMY
2225546500052RETELENASIMSONFN
5516229600045RETDARIOPENTALMN
5356222750055RETELENASIMSONFN
2221889540012RETMARCTESCOMY
245568812500502CORPNULLNULLNULLNULL
13224886562500511CORPNULLNULLNULLNULL
13235987953100521CORPNULLNULLNULLNULL
13231115951220531CORPNULLNULLNULLNULL

Join sinistro - conto con cliente

Si noti che attributi come nome, cognome, sesso e stato civile nelle ultime quattro righe sono popolati con NULLs. Questo perché queste righe grigie non hanno corrispondenze nella tabella (cioè ). customer (cioè i valori customer_id di 50, 51 , 52 e 53 non sono presenti nella tabella). customer tabella). Pertanto, questi attributi sono stati lasciati NULL in questo risultato.

GIUNTA A DESTRA

Analogamente a LEFT JOIN, RIGHT JOIN conserva tutti i record della tabella di destra (anche se non ci sono record corrispondenti nella tabella di sinistra). Ecco un'immagine familiare per mostrarvi come funziona:

GIUNTA DESTRA

Ancora una volta, utilizziamo lo stesso esempio. Tuttavia, abbiamo sostituito LEFT JOIN con RIGHT JOIN:

SELECT account.account_id,
      account.overdraft_amount,
      account.type_id,
      account.segment,
      account.customer_id,
      customer.customer_id
      customer.name,
      customer.lastname,
      customer.gender,
      customer.marital_status
FROM account 
RIGHT JOIN customer 
ON account.customer_id=customer.customer_id;

La sintassi è per lo più la stessa. Ho apportato un'altra piccola modifica: Oltre a account.customer_id, ho aggiunto anche la colonna customer.customer_id all'insieme dei risultati. L'ho fatto per mostrare cosa succede ai record della tabella customer che non hanno una corrispondenza nella tabella di sinistra (account).

Ecco il risultato:

account_idoverdraft_amounttype_idsegmentcustomer_idcustomer_idnamelastnamegendermarital_status
132359879515501RET11MARCTESCOMY
222188954002RET11MARCTESCOMY
NULLNULLNULLNULLNULL2ANNAMARTINFN
NULLNULLNULLNULLNULL3EMMAJOHNSONFY
2556889120002RET44DARIOPENTALMN
551622960005RET44DARIOPENTALMN
222554650002RET55ELENASIMSONFN
535622275005RET55ELENASIMSONFN
NULLNULLNULLNULLNULL6TIMROBITHMN
NULLNULLNULLNULLNULL7MILAMORRISFN
NULLNULLNULLNULLNULL8JENNYDWARTHFY

Risultato della GIUNTA DESTRA

Come si può vedere, tutti i record della tabella di destra sono stati inclusi nel set di risultati. Si tenga presente che

  • Gli ID cliente non corrispondenti della tabella di destra (numeri 2, 3, 6, 7 e 8, in grigio) hanno gli attributi del conto impostati su NULL in questo set di risultati. Si tratta di clienti al dettaglio che non hanno un conto bancario e quindi nessun record nella tabella. account tabella.
  • Ci si potrebbe aspettare che la tabella risultante abbia otto record, perché questo è il numero totale di record della tabella. customer tabella. Tuttavia, non è così. Abbiamo 11 record perché gli ID cliente 1, 4 e 5 hanno ciascuno due conti nella tabella. account tabella. Vengono visualizzate tutte le possibili corrispondenze.

JOIN COMPLETO (ESTERNO)

Vi ho mostrato come mantenere tutti i record della tabella di sinistra o di quella di destra. Ma cosa succede se si vogliono conservare tutti i record di entrambe le tabelle? Nel nostro caso, vorremmo visualizzare tutti i record corrispondenti più tutti gli account aziendali più tutti i clienti senza account. A tale scopo, si può utilizzare il tipo FULL OUTER JOIN. Questo tipo JOIN accoppierà tutte le colonne corrispondenti e visualizzerà anche tutte le colonne non corrispondenti di entrambe le tabelle. Gli attributi non familiari saranno popolati con NULLs. Si veda l'immagine seguente:

JOIN COMPLETO (ESTERNO)

Ecco la sintassi completa di OUTER JOIN:

SELECT account.*,
      CASE WHEN customer.customer_id IS NULL
                 THEN account.customer_id 
                 ELSE customer.customer_id 
       END customer_id
      customer.name,
      customer.lastname,
      customer.gender,
      customer.marital_status
FROM account 
FULL JOIN customer 

ON account.customer_id=customer.customer_id;

Ora il risultato appare come segue:

account_idoverdraft_amountcustomer_idtype_idsegmentnamelastnamegendermarital_status
25568891200042RETDARIOPENTALMN
1323598795155011RETMARCTESCOMY
2225546500052RETELENASIMSONFN
5516229600045RETDARIOPENTALMN
5356222750055RETELENASIMSONFN
2221889540012RETMARCTESCOMY
245568812500502CORPNULLNULLNULLNULL
13224886562500511CORPNULLNULLNULLNULL
13235987953100521CORPNULLNULLNULLNULL
13231115951220531CORPNULLNULLNULLNULL
NULLNULL2NULLNULLANNAMARTINFN
NULLNULL3NULLNULLEMMAJOHNSONFY
NULLNULL6NULLNULLTIMROBITHMN
NULLNULL7NULLNULLMILAMORRISFN
NULLNULL8NULLNULLJENNYDWARTHFY

Risultato della join esterna completa

Si noti che nelle ultime cinque righe gli attributi dei conti sono popolati da NULL. Questo perché questi clienti non hanno record nella tabella. account tabella. Si noti anche che i clienti 50, 51, 52 e 53 hanno nomi o cognomi e altri attributi della tabella popolati con NULL. customer tabella popolati con NULL. Questo perché non esistono nella tabella. customer tabella. In questo caso, customer_id nella tabella dei risultati non è mai NULL perché abbiamo definito customer_id con un'istruzione CASE WHEN:

CASE WHEN customer.customer_id IS NULL
                 THEN account.customer_id 
                 ELSE customer.customer_id END customer_id

Questo significa che customer_id nella tabella dei risultati è una combinazione di account.customer_id e customer.customer_id (cioè quando una è NULL, si usa l'altra). Potremmo anche visualizzare entrambe le colonne nell'output, ma questa istruzione CASE WHEN è più comoda.

Non c'è problema se tutti i diversi SQL JOINs e le loro funzioni vi confondono. Basta seguire la procedura. Vi consiglio di consultare il nostro foglio informativo sulle JOIN SQL. Tenetelo vicino a voi; è molto utile durante la codifica. È utile anche rivedere il nostro articolo sulla pratica di SQL JOINs. Più si impara e si fa pratica, più SQL JOINs sarà chiaro.

Prossimamente: Pratica SQL JOINs

In questo articolo abbiamo introdotto diversi tipi di SQL JOIN. I join interni, a sinistra, a destra e completi restituiscono tutti risultati diversi. Ora è necessario mettere in pratica queste conoscenze! A LearnSQL.it è possibile trovare altri esempi su cui esercitarsi. Le nostre SQL JOINs coprono gli argomenti delle JOIN, quindi vi invito a provarli.