back to top

Diversi tipi di JOIN in SQL Server: INNER JOIN, OUTER JOIN e CROSS JOIN

Nelle applicazioni reali solitamente ci si trova ad operare su grandi moli di dati distribuiti su più tabelle. In questi contesti risulta molto utile la clausola JOIN del linguaggio SQL che serve a combinare i dati di due o più tabelle basandosi su alcune condizioni logiche.

In particolare in SQL Server esistono tre differenti tipi di JOIN:

  • INNER JOIN
  • OUTER JOIN
  • CROSS JOIN

Per comprendere le differenze tra le diverse tipologie di JOIN supponiamo di operare su un database dove abbiamo definito due tabelle denominate "Dipendenti" e "Aree" così strutturato:

CREATE TABLE [dbo].[Dipendenti](
  [IdDipendente] [int] IDENTITY(1,1) NOT NULL,
  [Cognome] [nvarchar](150) NOT NULL,
  [Nome] [nvarchar](150) NULL,
  [Email] [nvarchar](150) NULL,
  [IdArea] [int] NULL,
PRIMARY KEY CLUSTERED 
(
  [IdDipendente] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

CREATE TABLE [dbo].[Aree](
  [IdArea] [int] IDENTITY(1,1) NOT NULL,
  [NomeArea] [nvarchar](255) NOT NULL,
PRIMARY KEY CLUSTERED 
(
  [IdArea] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

Il legame tra le due tabelle è costituito dal campo "IdArea" che indica l’area aziendale a cui ogni dipendente appartiene (ma non necessariamente tutti i dipendenti sono associati ad un’area aziendale come vedremo).

Dopo aver creato queste tabelle popoliamole con alcuni dati:

Popoliamo di dati la tabella Dipendenti
Popoliamo di dati la tabella Aree

A questo punto abbiamo tutti gli elementi per analizzare i diversi tipi di JOIN.

INNER JOIN in SQL Server

Questo tipo di JOIN restituisce tutte le righe delle tabelle coinvolte in cui esista una corrispondenza tra i valori delle colonne presenti nella clausola ON. Nel nostro caso potremmo utilizzare questo tipo di JOIN se vogliamo ottenere id, nome, cognome e area di tutti i dipendenti assegnati ad un’area aziendale:

SELECT D.IdDipendente,D.Nome,D.Cognome,A.NomeArea
FROM dbo.Dipendenti D
    INNER JOIN dbo.Aree A
      ON A.IdArea = D.IdArea

Questa query restituisce il seguente result set:

Risultato della nostra query con INNER JOIN

Con l’INNER JOIN vengono escluse quelle righe della tabella Dipendenti che non hanno una corrispondenza con la tabella Aree in base al campo specificato nella clausola ON del JOIN (quindi IdArea) e cioè le righe evidenziate nella seguente immagine:

Record della tabella Dipendenti esclusi dalla query precedente

In questo caso vengono esclusi i dipendenti con IdDipendente 5 e 6 perché essi non sono assegnati ad alcuna area.

OUTER JOIN in SQL Server

A sua volta l’OUTER JOIN in SQL Server può essere di tre tipi:

  • LEFT OUTER JOIN
  • RIGHT OUTER JOIN
  • FULL OUTER JOIN

Questo tipo di JOIN quando si desidera selezionare tutte le righe della tabella che si trova a sinistra (LEFT) o a destra (RIGHT) della clausola di JOIN o quando si desidera selezionare tutte le righe di entrambe (FULL), indipendentemente dalla corrispondenza tra i campi presenti nella clausola ON.

Nel nostro caso potremmo utilizzare questo tipo di JOIN se vogliamo ottenere id, nome, cognome e area di tutti i dipendenti indipendentemente dal fatto che essi siano assegnati effettivamente ad un’area. Per fare ciò basta sostituire nella query che abbiamo visto in precedenza alla clausola INNER JOIN la clausola LEFT OUTER JOIN

SELECT D.IdDipendente,D.Nome,D.Cognome,A.NomeArea
FROM dbo.Dipendenti D
    LEFT OUTER JOIN dbo.Aree A
      ON A.IdArea = D.IdArea

In questo caso il risultato è il seguente:

Risultato di LEFT OUTER JOIN

Vengono restituiti tutti i record della tabella a sinistra del JOIN (cioè Dipendenti) anche se non tutti i record hanno un valore nel campo IdArea. Quindi in pratica se c’è una corrispondenza tra le due tabelle viene riportata la relativa area, se non c’è vengono comunque riportati i dati dei dipendenti.

Supponiamo adesso di voler visualizzare il nome di tutte le aree aziendali indipendentemente dal fatto che ad esse appartengano dipendenti. Potremmo allora scrivere:

SELECT A.NomeArea,D.IdDipendente,D.Nome,D.Cognome
FROM dbo.Dipendenti D
    RIGHT OUTER JOIN dbo.Aree A
      ON A.IdArea = D.IdArea

Il risultato della query sarà allora il seguente:

Risultato di RIGHT OUTER JOIN

Vengono restituiti tutti i record della tabella a destra del JOIN (cioè Aree) anche se non tutti i record hanno una corrispondenza con la tabella a sinistra (cioè Dipendenti). Quindi in pratica se c’è una corrispondenza tra le due tabelle viene riportato il relativo dipendente (o dipendenti, infatti alcune righe vengono duplicate), se non c’è vengono comunque riportati i dati delle aree.

Se invece vogliamo ottenere tutti i dati di entrambe le tabelle indipendentemente dall’esistenza di una corrispondenza tra le stesse possiamo utilizzare il FULL OUTER JOIN:

SELECT D.IdDipendente,D.Nome,D.Cognome,A.NomeArea
FROM dbo.Dipendenti D
    FULL OUTER JOIN dbo.Aree A
      ON A.IdArea = D.IdArea

Il risultato di questa query è il seguente:

Risultato di FULL OUTER JOIN

Quindi vengono restituiti tutti i record di entrambe le tabelle. Se esiste una corrispondenza dipendente-area tutti i campi della relativa riga contengono valori, altrimenti i campi vengono presentati con valori NULL.

CROSS JOIN in SQL Server

Questo tipo di join combina tutte le righe della tabella a sinistra con tutte le righe della tabella a destra e serve quando si desidera selezionare tutte le possibili combinazioni di righe e colonne da entrambe le tabelle. Quindi se nelle nostra tabelle abbiamo rispettivamente 6 e 4 righe il risultato di questo tipo di JOIN darà 24 righe (6×4):

SELECT D.IdDipendente,D.Nome,D.Cognome,A.NomeArea
FROM dbo.Dipendenti D
    CROSS JOIN dbo.Aree A
Risultato di CROSS JOIN

Da notare che in questo tipo di JOIN la clausola ON ovviamente non va specificata. Esso richiede molto tempo per l’esecuzione rispetto agli altri JOIN e restituisce risultati la cui utilità è molto limitata se non per specifici scopi.

Conclusioni

Concludendo quindi possiamo dire che i JOIN vengono utilizzati per estrapolare dati da più tabelle in un’unica query. Chiaramente nei nostri esempi abbiamo utilizzato un solo JOIN ma in una stessa query possono essere combinate più tabelle con diversi tipi di JOIN. Inoltre per migliorare le prestazioni dei JOIN è opportuno limitare il numero di righe coinvolte in queste operazioni mediante la specifica di una clausola WHERE nella query. E’ bene ricordare, infine, che le prestazioni dei JOIN sono migliori quando le colonne utilizzate per collegare le tabelle sono indicizzate.

Pubblicitร 

Leggi anche...

Come ottenere l’ID dell’ultimo record inserito in MySQL, PostgreSQL, SQL Server e Oracle?

Ottenere l'ID dell'ultimo record inserito in una tabella, dopo...

Database completo regioni, province e comuni italiani (in formato SQL)

Quando si sviluppa un sito web o un'applicazione in...

File CSV: cosa sono, come si aprono e come crearli

In questo articolo cercheremo di capire cos'รจ il formato...

Confrontare due tabelle e trovare i record senza corrispondenza

all'interno di un database relazionale può essere utile poter...

Eseguire comandi SQL online con SQL Fiddle

Sì. E' possibile testare codice SQL senza aver installato...

SQL: Calcolare la media dei valori di più campi

Attraverso una semplice query SQL è possibile calcolare dinamicamente...
Pubblicitร