Pagina personale di:
Carlo Vecchio
appunti di C#, R, SQL Server, ASP.NET, algoritmi, numeri
Vai ai contenuti

SQL Server - Join

SQL Server

Join

  • I Join tra le tabelle sono utilizzati per estrarre dati tra 2 o più tabelle e specificano il modo in cui le tabelle sono collegate.
  • Esistono diversi tipi di Join e in base al Join utilizzato i risultati estratti sono diversi.
  • In SQL Server esistono i seguenti tipi di Join:

- Inner Join o Join
- Outer Join, suddivisi in:
- Left Join o Left Outer Join
- Right Join o Right Outer Join
- Full Join o Full Outer Join
- Cross Join

Dati di esempio
  • Si abbiano le seguenti tabelle con i record indicati. Si noti che la tabella ‘tblPersone’ ha un record con un ‘IdCittà’ che non ha un corrispettivo nella tabella ‘tblCittà’. Analogamente la tabella ‘tblCittà’ ha un record il cui ‘IdCittà’ non è presente nella tabella ‘tblPersone’.

   CREATE TABLE tblPersone
   (
       IdPersona    INT PRIMARY KEY IDENTITY(1,1) NOT NULL,
       NomePersona  NVARCHAR(50) NULL,
       IdCittà      INT
   )

   CREATE TABLE tblCittà
   (
       IdCittà      INT PRIMARY KEY NOT NULL,
       NomeCittà    NVARCHAR(50) NULL
   )

   INSERT INTO tblPersone
   VALUES
    ('Carlo', 1),
    ('Mario', 2),
    ('Piero', 1),
    ('Mauro', 3),
    ('Aldo', 4)

   INSERT INTO tblCittà
   VALUES
    (1, 'Milano'),
    (2, 'Roma'),
    (3, 'Torino'),
    (5, 'Padova')

  • Nei Join tipicamente si considera una tabella come ‘principale’ ed è posta a sinistra. In questa tabella uno o più campi sono chiavi esterne di altre tabelle che sono poste a destra. Nell’esempio precedente il campo ‘IdCittà’ è la chiave esterna.

Sintassi generale (semplificata)
  • Questa è la sintassi generale delle SQL con i Join. In ‘tipo_join’ va messo il tipo di join da utilizzare, cioè uno tra ‘INNER JOIN’ (analogo a ‘JOIN’), ‘LEFT JOIN’ (analogo a ‘LEFT OUTER JOIN’), ‘RIGHT JOIN’ (analogo a ‘RIGHT OUTER JOIN’), ‘FULL JOIN’ (analogo a ‘FULL OUTER JOIN’), ‘CROSS JOIN’.
  • Nella condizione ‘ON’ va messo il legame tra le due tabelle e di solito è costituito dall’uguaglianza tra la chiave esterna della tabella di sinistra con la chiave univoca della tabella di destra.

   SELECT elenco_campi
   FROM tabella1
   tipo_join tabella2 ON tabella1.campo = tabella2.campo


Inner Join o Join

  • Restituisce una tabella combinando le righe della tabella di sinistra (tblPersone) con quelle della tabella di destra (tblCittà). Non restituisce le righe della tabella di sinistra che non hanno una corrispondente riga nella tabella di destra e viceversa.
  • Graficamente:



  • Query:

   SELECT *
   FROM tblPersone
   INNER JOIN tblCittà ON tblPersone.IdCittà = tblCittà.IdCittà

  • Oppure:

   SELECT *
   FROM tblPersone
   JOIN tblCittà ON tblPersone.IdCittà = tblCittà.IdCittà

  • Risultato:

IdPersona   NomePersona   IdCittà   IdCittà   NomeCittà
-------------------------------------------------------
       1   Carlo               1         1   Milano
       2   Mario               2         2   Roma
       3   Piero               1         1   Milano
       4   Mauro               3         3   Torino
 
  • Commento:
  • Come si vede nella tabella dei risultati, non compare il record con IdPersona = 5 perché è associato all’IdCittà = 4 che non esiste. E non compare nessun record con IdCittà = 5, perché nessuna persona è associata all’IdCittà = 5.
 

Left Outer Join o Left Join

  • Restituisce tutte le righe della tabella di sinistra (tblPersone) indipendentemente dal fatto che esista una corrispondenza con la tabella di destra. Se nella tabella di destra (tblCittà) non è trovata una corrispondenza, i relativi campi sono restituiti NULL.
  • Graficamente:



  • Query:

   SELECT *
   FROM tblPersone
   LEFT JOIN tblCittà ON tblPersone.IdCittà = tblCittà.IdCittà

  • Oppure:

   SELECT *
   FROM tblPersone
   LEFT OUTER JOIN tblCittà ON tblPersone.IdCittà = tblCittà.IdCittà

  • Risultato:

IdPersona   NomePersona   IdCittà   IdCittà   NomeCittà
-------------------------------------------------------
       1   Carlo               1         1   Milano
       2   Mario               2         2   Roma
       3   Piero               1         1   Milano
       4   Mauro               3         3   Torino
       5   Aldo                4      NULL   NULL

  • Commento:
  • Il risultato presenta tante righe quante sono le righe della tabella di sinistra. Nell’ultima riga, con IdCittà = 4, che non ha una corrispondenza nella tabella di destra, sono restituiti valori NULL al posto delle colonne della tabella di destra.

Right Outer Join o Right Join
  • Restituisce tutte le righe della tabella di destra (tblCittà). Se nella tabella di sinistra (tblPersone) sono trovate una o più corrispondenze, esse sono mostrare. Se non sono trovate corrispondenze, allora i relativi campi sono NULL.
  • Graficamente:



  • Query:

   SELECT *
   FROM tblPersone
   RIGHT JOIN tblCittà ON tblPersone.IdCittà = tblCittà.IdCittà

  • Oppure:

   SELECT *
   FROM tblPersone
   RIGHT OUTER JOIN tblCittà ON tblPersone.IdCittà = tblCittà.IdCittà

  • Risultato:

IdPersona   NomePersona   IdCittà   IdCittà   NomeCittà
-------------------------------------------------------
       1   Carlo               1         1   Milano
       3   Piero               1         1   Milano
       2   Mario               2         2   Roma
       4   Mauro               3         3   Torino
    NULL   NULL             NULL         5   Padova

  • Commento:
  • Nel risultato c’è almeno una riga per ogni riga della tabella di destra. Per IdCittà = 1 sono estratti due record, in quanto due persone sono associate a quella città. Per IdCittà = 5 è estratto comunque un record ma i campi della tabella tblPersone sono a NULL.

Full Outer Join o Full Join

  • È l’unione del Left Join con il Right Join, quindi resituisce tutte le righe per le quali c’è una corrispondenza tra la tabella di sinistra e quella di destra, più tutte le righe per le quali non c’è una corrispondenza sia in un senso (sinistra – destra) che nell’altro (destra – sinistra).
  • Graficamente:



  • Query:

   SELECT *
   FROM tblPersone
   FULL OUTER JOIN tblCittà ON tblPersone.IdCittà = tblCittà.IdCittà

  • Oppure:

   SELECT *
   FROM tblPersone
   FULL JOIN tblCittà ON tblPersone.IdCittà = tblCittà.IdCittà

  • Risultato:

IdPersona   NomePersona   IdCittà   IdCittà   NomeCittà
-------------------------------------------------------
       1   Carlo               1         1   Milano
       2   Mario               2         2   Roma
       3   Piero               1         1   Milano
       4   Mauro               3         3   Torino
       5   Aldo                4      NULL   NULL
    NULL   NULL             NULL         5   Padova

  • Commento:
  • Come si vede dal risultato, le prime quattro righe sono quelle dove è trovata una corrispondenza tra la chiave esterna della tabella di sinistra e la chiave univoca della tabella di destra. La quinta riga mostra la persona con IdPersona = 5 per la quale non c’è corrispondenza nella tabella tblCittà. La sesta riga mostra invece la città con IdCittà = 5 per la quale non c’è nessuna persona della tabella tblPersone.

Cross Join
  • Il Cross Join tra due tabelle è detto ‘prodotto cartesiano’ tra le due tabelle. Sono restituiti tanti record quante sono le combinazioni tra i record della prima tabella con quelli della seconda tabella.
  • Se, per esempio, le due tabelle hanno rispettivamente 10 e 3 righe, il Cross Join restituisce 30 righe.
  • È un Join che non cerca corrispondenze tra le due tabelle, quindi non ha nella sintassi la parte con ‘ON’.
  • Query:

   SELECT *
   FROM tblPersone
   CROSS JOIN tblCittà

  • Risultato:

IdPersona   NomePersona   IdCittà   IdCittà   NomeCittà
-------------------------------------------------------
       1   Carlo               1         1   Milano
       2   Mario               2         1   Milano
       3   Piero               1         1   Milano
       4   Mauro               3         1   Milano
       5   Aldo                4         1   Milano
       1   Carlo               1         2   Roma
       2   Mario               2         2   Roma
       3   Piero               1         2   Roma
       4   Mauro               3         2   Roma
       5   Aldo                4         2   Roma
       1   Carlo               1         3   Torino
       2   Mario               2         3   Torino
       3   Piero               1         3   Torino
       4   Mauro               3         3   Torino
       5   Aldo                4         3   Torino
       1   Carlo               1         5   Padova
       2   Mario               2         5   Padova
       3   Piero               1         5   Padova
       4   Mauro               3         5   Padova
       5   Aldo                4         5  Padova

  • Commento:
  • Sono estratte 20 righe che sono tutte le combinazioni tra le 5 righe della tabella tblPersone e le 4 righe della tabella tblCittà.

Altri Join
  • In alcune situazioni può essere utile estrarre sole le righe della tabella di sinistra che non hanno righe corrispondenti nella tabella di destra, o viceversa. Si fa sempre riferimento alle tabelle definite sopra.
  • Righe della tabella di sinistra senza corrispondenza nella tabella di destra:



   SELECT *
   FROM tblPersone
   LEFT JOIN tblCittà ON tblPersone.IdCittà = tblCittà.IdCittà
   WHERE tblCittà.IdCittà IS NULL

  • Risultato:

IdPersona   NomePersona   IdCittà   IdCittà   NomeCittà
-------------------------------------------------------
       5   Aldo                4      NULL   NULL

  • Righe della tabella di destra senza corrispondenza nella tabella di sinistra:



   SELECT *
   FROM tblPersone
   RIGHT JOIN tblCittà ON tblPersone.IdCittà = tblCittà.IdCittà
   WHERE tblPersone.IdCittà IS NULL

  • Risultato:

IdPersona   NomePersona   IdCittà   IdCittà   NomeCittà
-------------------------------------------------------
    NULL   NULL             NULL         5   Padova

  • Righe di entrambe le tabelle senza corrispondenza nell’altra tabella:



   SELECT *
   FROM tblPersone
   FULL JOIN tblCittà ON tblPersone.IdCittà = tblCittà.IdCittà
   WHERE tblCittà.IdCittà IS NULL OR tblPersone.IdCittà IS NULL

  • Risultato:

IdPersona   NomePersona   IdCittà   IdCittà   NomeCittà
-------------------------------------------------------
       5   Aldo                4      NULL   NULL
    NULL   NULL             NULL         5   Padova

© 2020 Carlo Vecchio
Torna ai contenuti