Come utilizzare le operazioni di join tra tabelle in Transact-SQL: CROSS JOIN e INNER JOIN

Datamaze
29.07.21 09:36 AM Comment(s)

A cosa servono le operazioni di JOIN

Solitamente le tabelle sono relazionate attraverso i campi chiave, come per esempio chiavi esterne e chiavi primarie. Possiamo utilizzare delle operazioni di JOIN per interrogare i dati da tabelle diverse e correlare i record (le righe) che sono in relazione tra loro. Andiamo quindi ad esaminare le prime due tipologie di join in SQL Server.


CROSS JOIN

E’ la tipologia di JOIN più semplice, ma non la più utilizzata.

Questo tipo di JOIN produce il prodotto cartesiano delle due (o più) tabelle utilizzate nella query.

In altre parole, viene fatta una moltiplicazione tra le tabelle, con il risultato di avere un record per ogni combinazione di righe da entrambe le tabelle.

 

Se si hanno record X nella tabella TAB1 e record Y nella tabella TAB2, il risultato della Cross Join sarà una tabella virtuale con X x Y righe.

SQL Cross join

La tabella di sinistra ha 2 righe con i valori chiave A e B.

La tabella di destra ha 3 righe con i valori A1, B2, C1.

Il risultato è una tabella con 6 righe contenenti tutte le combinazioni possibili delle righe delle due tabelle di origine.


Alcuni consigli per l'utilizzo di CROSS JOIN

E’ possibile utilizzare una CROSS JOIN tra due istanze della stessa tabella.

Un esempio semplice è quello di utilizzare una tabella che ha un unico campo (n) contenente una sequenza di numeri progressivi da 1 in avanti.

 

L'idea è di partire da questa tabella e, tramite l’operazione di CROSS JOIN, generare un risultato dove ogni riga è formata da 2 valori: un primo campo rappresenta il giorno della settimana (da 1 a 7) mentre il secondo campo rappresenta il turno di quella giornata (immaginiamo una giornata divisa in 4 turni da 1 a 4) .

 

Il risultato che si vuole ottenere è quello di avere una riga per ogni giorno della settimana (da 1 a 7) ed un numero di slot (da 1 a 4), volendo suddividere ogni giorno in quattro slot diversi.

Il risultato potrebbe essere utilizzato poi per la gestione delle attività effettuate negli slot presenti nei diversi giorni.

 

Il risultato sarà quello di avere 28 righe totali con 4 turni slot per ognuno dei 7 giorni della settimana.

Questo il codice utilizzato:

SELECT G.n AS Giorno, S.n AS Slot
FROM TabContatore AS G
	CROSS JOIN TabContatore AS S
WHERE G.n <= 7 AND S.n<=4
ORDER BY Giorno, Slot

Un consiglio sulla sintassi

Entrambi i linguaggi standard SQL e T-SQL supportano una sintassi meno recente con la quale è possibile specificare una virgola tra i nomi delle tabelle come riportato qui sotto:

“… FROM TAB1, TAB2”

In ogni caso la best practice è quella di utilizzare la nuova sintassi riportata in precedenza, in quanto di più facile lettura e meno soggetta ad errori.


INNER JOIN

Con l’operazione di  INNER JOIN, è possibile combinare le righe a partire da due (o più) tabelle basandosi su un predicato, che solitamente compara da una parte una chiave primaria e dall’altra parte una chiave esterna.

SQL Inner join

Le chiavi primarie e quelle esterne sono rappresentate dalle lettere rispettivamente nella tabella di sinistra ed in quella di destra.

 

Ipotizzando che la JOIN sia una equijoin (ovvero utilizza un predicato con operatore di uguaglianza, =), la INNER JOIN restituirà solo le righe per cui il predicato sarà valutato a vero. Le righe per cui il predicato sarà valutato a falso oppure sconosciuto (come nel caso di confronto con NULL),saranno escluse dal risultato finale. Il predicato per la corrispondenza all’interno della JOIN è specificato nella clausola ON.

 

Un esempio di query con INNER JOIN:

SELECT
	T1.campo1, T1.campo2,
	T2.campo1, T2.campo2, T2.campo3
FROM
	TAB1 AS T1
	INNER JOIN TAB2 AS T2
	ON T1.campochiave=T2.campochiave
WHERE
	T1.campo4=’123’
Osserviamo l’utilizzo degli alias al posto dei nomi tabella originali. La convenienza riguarda il  riferimento a nomi di campo ambigui: tale utilizzo di alias è obbligatorio al fine di evitare ambiguità tra i campi coinvolti nell’operazione, come nell’esempio del campo chiave. L’utilizzo degli alias per i nomi di campi non ambigui non è obbligatorio ma è considerato una best practice.


Una domanda comune è: “Qual è la differenza tra le clausole ON e WHERE, e cambia qualcosa specificare il predicato in una o nell’altra?”  Si tratta di una differenza molto importante, che può scatenare comportamenti molto diversi a seconda dell’utilizzo. Nel caso delle INNER JOIN, la risposta è che non vi è alcuna differenza.

Entrambe le clausole servono allo stesso scopo di filtro e mantengono validi solamente i record per cui il predicato sarà valutato a vero, scartando le righe per le quali il predicato sarà valutato a falso o sconosciuto.

Per questo è possibile riorganizzare la posizione dei predicati della query precedente, specificandoli entrambi nella clausola ON e mantenendo la stessa logica, come segue:
SELECT
	T1.campo1, T1.campo2,
	T2.campo1, T2.campo2, T2.campo3
FROM
TAB1 AS T1
	INNER JOIN TAB2 AS T2
	ON T1.campochiave=T2.campochiave
		AND T1.campo4=’123’

Un ulteriore esempio per una INNER JOIN è quello di mettere in join due istanze della stessa tabella come nell’esempio seguente:

SELECT
	D.IDDipendente,
	D.Nome + N' ' + D.Cognome AS Dipendente,
	M.Nome + N' ' + M.Cognome AS Manager
FROM Dipendenti AS D
	INNER JOIN Dipendenti AS M
		ON D.IDManager = M.IDDipendente

Da osservare il predicato join: ON D.IDManager = M.IDDipendente.

L’istanza Dipendente ha come alias D e l’istanza Manager ha come istanza M

Per trovare i record correlati, l’IDManager relativo al Dipendente deve essere uguale all’IDDipendente del manager corrispondente.


Consigli sulla sintassi

Come per le CROSS JOIN, entrambi i linguaggi standard SQL e T-SQL supportano una sintassi meno recente con la quale è possibile specificare una virgola tra i nomi delle tabelle e su tutti i predicati nella clausola WHERE. Viene considerata una best practice attenersi alla nuova sintassi con la parola chiave JOIN.


Utilizzando la vecchia sintassi, se si dimentica di indicare il predicato JOIN, si finirà con una CROSS JOIN non intenzionale. Utilizzando la nuova sintassi, una INNER JOIN non sarà valida sintatticamente senza una clausola ON, quindi, se si dimentica di indicare il predicato JOIN, sarà generato un errore.


Dato che la INNER JOIN è la tipologia di join più comune, nello standard è stato deciso di impostarla come default nel caso in cui venga specificata solo la parola chiave JOIN.


Quindi T1 JOIN T2 è equivalente a scrivere T1 INNER JOIN T2.


Conclusioni

Abbiamo visto due tipologie di JOIN in SQL Server. Nel prossimo articolo andremo ad analizzare come funziona e come si utilizza la tipologia OUTER JOIN.


Gli esempi utilizzati in questo articolo sono tratti dal libro "Exam Ref 70-761 Querying Data with Transact-SQL" di Itzik Ben-Gan.


di Alice Sella, pubblicato il 29 luglio 2021