Informazioni sui concetti e sulla sintassi delle operazioni join
Il metodo di base più comune per combinare i dati di più tabelle consiste nell'utilizzo di un'operazione JOIN. Alcuni utenti considerano l'operazione JOIN come clausola separata di un'istruzione SELECT, altri come parte della clausola FROM. In questo modulo, JOIN verrà considerata principalmente come parte della clausola FROM. Si scoprirà come la clausola FROM in un'istruzione T-SQL SELECT consenta di crea tabelle virtuali intermedie da utilizzare nelle fasi successive della query.
Clausola FROM e tabelle virtuali
Gli utenti che conoscono l'ordine logico delle operazioni eseguite quando SQL Server elabora una query sanno che la clausola FROM di un'istruzione SELECT è la prima clausola a essere elaborata. Questa clausola determina quale tabella o quali tabelle costituiranno l'origine delle righe per la query. FROM può fare riferimento a una singola tabella o riunire più tabelle come origine dei dati per la query. Si può immaginare la clausola FROM come la creazione e il popolamento di una tabella virtuale. Questa tabella virtuale conterrà l'output della clausola FROM e verrà usata dalle clausole dell'istruzione SELECT applicate in un secondo momento, come la clausola WHERE. Se a una clausola FROM si aggiungono altre funzionalità, ad esempio operatori di join, è utile pensare allo scopo degli elementi della clausola FROM come aggiunta, o rimozione, di righe nella tabella virtuale.
La tabella virtuale creata da una clausola FROM è solo un'entità logica. In SQL Server non viene creata alcuna tabella fisica, persistente o temporanea, per contenere i risultati della clausola FROM, poiché la tabella virtuale viene passata alla clausola WHERE o ad altre parti della query.
La tabella virtuale creata dalla clausola FROM contiene i dati di tutte le tabelle unite in join. Può essere utile considerare i risultati come insiemi e concettualizzare i risultati di join come un Diagramma Venn.
Nel corso del tempo, il linguaggio T-SQL è stato ampliato per riflettere le modifiche apportate agli standard American National Standards Institute (ANSI) per il linguaggio SQL. Una delle posizioni più importanti in cui queste modifiche sono visibili è la sintassi per i join in una clausola FROM. In base allo standard ANSI SQL-89, i join vengono specificati includendo più tabelle nella clausola FROM in un elenco delimitato da virgole. Eventuali filtri per determinare le righe da includere sono stati eseguiti nella clausola WHERE, come nell'esempio seguente:
SELECT p.ProductID, m.Name AS Model, p.Name AS Product
FROM SalesLT.Product AS p, SalesLT.ProductModel AS m
WHERE p.ProductModelID = m.ProductModelID;
Questa sintassi è ancora supportata da SQL Server, ma a causa della complessità di rappresentazione dei filtri per i join complessi, non è consigliata. Inoltre, se si omette accidentalmente una clausola WHERE, i join di tipo ANSI SQL-89 possono diventare facilmente prodotti cartesiani e restituire un numero eccessivo di righe di risultati, causando problemi di prestazioni e restituendo eventualmente risultati non corretti.
Per imparare a scrivere query per più tabelle in T-SQL, è importante comprendere il concetto di "prodotto cartesiano". In matematica, un prodotto cartesiano è il prodotto di due insiemi. Il prodotto di un insieme con 2 elementi e di un insieme con 6 elementi è un insieme di 12 elementi, ovvero 6 x 2. Ogni elemento di un insieme viene combinato con ogni elemento del secondo insieme. Nell'esempio seguente è mostrato un insieme di nomi con 2 elementi e un insieme di prodotti con 3 elementi. Il prodotto cartesiano combina ogni nome con ogni prodotto e produce 6 elementi.
Nei database, un prodotto cartesiano è il risultato della combinazione di ogni riga di una tabella con ogni riga di un'altra tabella. Il prodotto di una tabella con 10 righe e una tabella con 100 righe è un set di risultati con 1.000 righe. Il risultato sottostante di un'operazione JOIN è un prodotto cartesiano, ma per la maggior parte delle query T-SQL un prodotto cartesiano non corrisponde al risultato desiderato. In T-SQL, un prodotto cartesiano si ottiene quando due tabelle di input vengono unite in join senza considerare alcuna relazione tra di esse. Senza informazioni sulle relazioni, SQL Server Query Processor restituirà tutte le possibili combinazioni di righe. Anche se questo risultato può avere alcune applicazioni pratiche, ad esempio la generazione di dati di test, in genere non è utile e può avere impatto significativo sulle prestazioni.
Con l'avvento dello standard ANSI SQL-92, è stato aggiunto il supporto per le clausole con parole chiave JOIN e ON. Anche T-SQL supporta questa sintassi. I join vengono rappresentati nella clausola FROM tramite l'operatore JOIN appropriato. La relazione logica tra le tabelle, che diventa un predicato di filtro, viene specificata nella clausola ON.
Nell'esempio seguente viene ridefinita la query precedente con la sintassi più recente:
SELECT p.ProductID, m.Name AS Model, p.Name AS Product
FROM SalesLT.Product AS p
JOIN SalesLT.ProductModel AS m
ON p.ProductModelID = m.ProductModelID;
Nota
Con la sintassi ANSI SQL-92, è più difficile che venga creato accidentalmente un prodotto cartesiano. Dopo aver aggiunto la parola chiave JOIN, se manca una clausola ON verrà generato un errore di sintassi, a meno che l'operazione JOIN non venga specificata come CROSS JOIN.