Join SQL: come collegare dati tra tabelle

operatore Join con linguaggio SQL

In questo articolo vedremo come scrivere una JOIN con il linguaggio SQL per collegare i dati presenti in più tabelle di un database relazionale. Utilizzare correttamente l’operatore di JOIN in SQL è un aspetto importantissimo che chiunque si avvicini al mondo delle query deve imparare a padroneggiare.

 

Join SQL: la sintassi

Nella clausola SELECT possiamo scrivere più colonne separandole con una virgola. Di conseguenza, se abbiamo bisogno nella stessa query di più tabelle, ad esempio Clienti e Conti), un tentativo naturale sarebbe quello di scriverle nella FROM e separarle con una virgola (SPOILER: NON FATELO!)

SELECT  *
FROM    Clienti, 
        Conti

In questo modo però otterremmo tutte le combinazioni possibili tra le righe delle tabella. Se ad esempio la tabella Clienti ha diecimila righe e la tabella Conti ne ha mille, la query precedente restituirà 10000*1000 = 10000000 righe! Sì, avete letto bene, dieci milioni. Avete visto come è semplice intasare un database di produzione?

Tuttavia la maggior parte di queste combinazioni saranno errate dal punto di vista logico. Ci aspettiamo infatti che all’interno delle due tabella Conti e Clienti sia presente una colonna comune IdCliente: di tutte le combinazioni precedenti vogliamo lasciare solamente quelle dove i dati delle tue colonne combaciano. Arriviamo dunque a questa query:

SELECT  *
FROM    Clienti, 
        Conti
WHERE  
   Clienti.IdCliente = 
   Conti.IdCliente;

Per quanto corretta e ancora utilizzata da molti programmatori, questa modalità di combinare i dati tra tabelle è stata superata da una sintassi più moderna, che presenta numerosi vantaggi in termini di leggibilità e manutenibilità. Essa fa uso delle istruzioni JOIN e ON e ci permette di scrivere una query equivalente a quella precedente in questo modo:

SELECT   *
FROM     Clienti 
INNER JOIN Conti 
   ON Clienti.IdCliente = 
       Conti.IdCliente

In questa query abbiamo utilizzato una INNER JOIN, ma vedremo che non sarà l’unica tipologia possibile.

 

INNER JOIN e LEFT JOIN in SQL: query ed esempi

Nei primi minuti del video seguente ripasseremo insieme quanto visto nel paragrafo precedente, se volete saltate pure questa parte. Dal minuto 08:30 vedremo un esempio all’apparenza identico a quanto fatto prima, ma che in realtà ha un’importante differenza: dovrò sostituire INNER JOIN con LEFT JOIN. Se non vedi il video potrebbe dipendere dal fatto che non hai accettato un cookie del sito relativo a Youtube.

 

Differenze tra le diverse tipologie di JOIN

Oltre a INNER e LEFT, esistono ulteriori tipologie di Join. Analizziamo quattro query in cui l’unica differenza è “l’aggettivo” che precede l’operatore JOIN:

SELECT *
FROM Fatture
INNER/LEFT/RIGHT/FULL 
JOIN Fornitori
 ON Fatture.IdFornitore = 
   Fornitori.IdFornitore;
  • Con la Inner Join mostreremo solo le combinazioni valide, equivalentemente alla sintassi con la virgola e la condizione WHERE.
  • Con la Left Join mostreremo mostra le combinazioni valide e le fatture senza fornitori associati.
  • Con la Right Join mostra le combinazioni valide e in più fornitori senza fatture associate.
  • Con la Full Join mostra le combinazioni valide, più le fatture senza fornitori associati, più i fornitori senza fatture associate.

Un’ultima tipologia di JOIN è la Cross Join che non richiede l’operatore ON. Essa mostra tutte le possibili combinazioni ed è dunque equivalente a separare le due tabella con la virgola nella FROM, senza inserire nessuna condizione nella WHERE.

Curiosità: sapevi che su MySQL non esiste la full join? Puoi approfondire in questo link https://www.yimp.it/full-join-mysql/ come arrivare ad un risultato analogo.

 

Alleggeriamo la sintassi

Nella SELECT possiamo utilizzare l’AS per rinominare la colonna nell’output della query. Analogamente nella FROM possiamo usare l’AS per rinominare le tabelle all’interno della query  e alleggerire così la sintassi. Ad esempio nel caso precedente potremmo scrivere

SELECT 
   Fa.*,
   Fo.Denominazione 
FROM Fatture AS Fa
INNER JOIN Fornitori AS Fo
 ON Fa.IdFornitore = 
    Fo.IdFornitore;

Vi consiglio di utilizzare una rinomina breve e che faccia riferimento alla tabella originale. In teoria è obbligatorio far precedere il nome della colonna dal riferimento alla tabella solo nel caso in cui la colonna sia ripetuta identicamente in più di una tabella. Tuttavia il mio consiglio è di specificare la tabella in qualsiasi caso. Con poco sforzo in più, otterrete una query molto più leggibile e facile da ri-analizzare in futuro. Puoi leggere qui altre buone pratiche di sviluppo SQL.

 

Perché scegliere la sintassi con la JOIN esplicita

Ti riporto alcuni motivi per i quali preferisco esplicitare l’operatore JOIN e usare la condizione ON, invece di usare la virgola nella FROM e aggiungere una condizione nella WHERE

  • leggibilità: ricordiamo che l’SQL è un linguaggio english-Like, la query deve riflettere il modo di esprimersi nel nostro linguaggio naturale. Negli esempi di prima l’obiettivo è collegare le tabelle utilizzando la colonna in comune IdCliente. Per far questo la sintassi con la JOIN esplicita è sicuramente più chiara, basta pensare alla traduzione in italiano della parola JOIN. In questo modo teniamo ben distinta la porzione di codice che esplica il collegamento tra le tabelle, da quella dove impostiamo altri filtri sui dati (come ad esempio su un’ulteriore colonna come la Regione di Residenza). Senza la JOIN tale distinzione risulta più difficile. Pensate a cosa succede quando la query è più complessa e sono presenti numerosissime join e svariati filtri;
  • manutenitibilità: supponiamo di dover trasformare l’INNER JOIN in una LEFT JOIN. Se abbiamo già esplicitato la JOIN ci basterà modificare una parola! Altrimenti su molti database dovremo riscrivere completamente la query;
  • facilità di scrittura: supponiamo di voler eliminare temporaneamente la JOIN. Se ho utilizzato la WHERE per scrivere la condizione di collegamento l’operazione risulterà sicuramente più complessa e comprende il rischio di commentare per errore anche un filtro su un’altra colonna.

 

Gestire la presenza di null nelle Join in SQL

La presenza di NULL complica spesso la scrittura di una query soprattutto quando la condizione di JOIN coinvolge più colonne. Supponiamo ad esempio che la tabella dei clienti e dei conti devono essere collegate secondo questa specifica: devono avere lo stesso codice_conto e, se presente, lo stesso codice_valuta. Chi lavora in ambito banking avrà sicuramente riconosciuto questa specifica collegata alla presenza di conti in più valute.

Occorre fare molta attenzione perché la seguente query, all’apparenza corretta, esclude tutti quei conti che hanno NULL nella colonna codice_valuta

SELECT *
FROM   DimConto AS c
INNER JOIN SnapshotConto AS s
  ON c.codice_conto = 
       s.codice_conto
AND c.codice_valuta = 
      s.codice_valuta;

Per risolvere questa fastidiosa situazione, vi lascio un link ad un fantastico articolo di Itzik Ben Gan legato alla gestione del NULL. Vi riporto la soluzione più “elegante”:

SELECT  c.*, s.*
FROM   DimConto c
INNER JOIN SnapshotConto s
ON EXISTS(SELECT c.codice_conto, 
                c.codice_valuta
            INTERSECT
         SELECT s.codice_conto, 
                s.codice_valuta);

 

Continua a imparare

Torna su