TOP

Lezione SQL 11. Combinazione avanzata di tabelle (OUTER JOIN)

Nella sezione precedente, abbiamo considerato i modi più semplici per combinare le tabelle, utilizzando le frasi WHERE e INNER JOIN. Queste combinazioni sono chiamate combinazioni interne o combinazioni di equivalenza. Tuttavia, SQL ha nel suo arsenale molte più opzioni per unire le tabelle, ovvero esistono anche altri tipi di join: join esterni, join naturali e self-join. Ma prima consideriamo come assegnare alias alle tabelle, poiché in seguito saremo costretti a utilizzare nomi completi di campi (Table.Field), che senza abbreviazioni saranno molto difficili da utilizzare a causa della loro grande lunghezza.


1. Utilizzo degli alias di tabella (Alias)

Nella sezione precedente abbiamo imparato come utilizzare gli alias per fare riferimento a campi specifici della tabella o a campi calcolati. SQL ci consente anche di utilizzare alias invece di nomi di tabelle. Questo ci offre vantaggi come una sintassi SQL più breve e ci consente di utilizzare la stessa tabella più volte nell'istruzione SELECT.

Run SQLSELECT Seller_name, SUM(Amount) AS Sum1 
FROM Sellers AS S, Sumproduct AS SP 
WHERE S.City = SP.City 
GROUP BY Seller_name

Abbiamo visualizzato l'importo totale dei beni venduti per ciascun venditore. Nella nostra query SQL abbiamo utilizzato i seguenti alias: per il campo calcolato SUM(Amount) l'alias Sum1, per la tabella Sellers l'alias S e per Sumproduct l'alias SP. Tieni presente che gli alias di tabella possono essere utilizzati anche in altre frasi, come ORDER BY, GROUP BY e altre.

2. Autoconnessione (SELF JOIN)

Consideriamo un esempio. Supponiamo di dover conoscere l'indirizzo dei venditori che commerciano nello stesso paese di John Smith. Per fare ciò, creeremo la seguente richiesta:

Run SQLSELECT Address, City, Country, Seller_name
FROM Sellers
WHERE Country = (SELECT Country 
                 FROM Sellers 
                 WHERE Seller_name = 'John Smith')

Inoltre, possiamo risolvere questo problema tramite l'autoconnessione scrivendo il seguente codice:

Run SQLSELECT S1.Address, S1.City, S1.Country, S1.Seller_name
FROM Sellers AS S1, Sellers AS S2 
WHERE S1.Country = S2.Country AND S2.Seller_name = 'John Smith'

Per risolvere questo problema sono stati utilizzati pseudonimi. La prima volta alla tabella Sellers è stato assegnato l'alias S1, la seconda volta l'alias S2. Questi alias possono quindi essere utilizzati come nomi di tabelle. Nell'operatore WHERE aggiungiamo il prefisso S1 al nome di ciascun campo, in modo che il DBMS comprenda i campi di quale tabella deve essere generata (poiché abbiamo creato due tabelle virtuali da una tabella). La clausola WHERE prima unisce le tabelle e poi filtra i dati della seconda tabella in base al campo Seller_name per restituire solo i valori necessari.

I self-join vengono spesso utilizzati per sostituire le sottoquery che selezionano i dati dalla stessa tabella dell'operatore esterno SELECT. Sebbene il risultato finale sia lo stesso, molti DBMS elaborano i join molto più velocemente delle sottoquery. Vale la pena sperimentare per determinare quale query funziona più velocemente.

3. Combinazione naturale

Un'unione naturale è un'unione in cui si selezionano solo le colonne che non si ripetono. Questo di solito viene fatto scrivendo (SELECT *) per una tabella e specificando un elenco di campi per il resto delle tabelle. Esempio:

Run SQLSELECT SP.*, S.Country
FROM Sumproduct AS SP, Sellers AS S 
WHERE SP.City = S.City

In questo esempio il carattere jolly (*) viene utilizzato solo per la prima tabella. Tutte le altre colonne vengono specificate in modo esplicito, pertanto le colonne duplicate non vengono selezionate.

4. Combinazione esterna (OUTER JOIN)

Di solito, durante l'unione, le righe di una tabella vengono collegate alle righe corrispondenti di un'altra tabella, tuttavia, in alcuni casi, potrebbe essere necessario includere nel risultato righe che non hanno righe correlate in un'altra tabella (ovvero tutte vengono selezionate le righe di una tabella e vengono aggiunte solo le righe correlate di un'altra). Una connessione di questo tipo è detta esterna. A questo scopo vengono utilizzate le parole chiave OUTER JOIN ... ON ... con il prefisso LEFT o RIGHT.

Consideriamo un esempio, avendo precedentemente aggiunto un nuovo venditore - Semuel Piter, che non ha ancora effettuato vendite, alla tabella Sellers:

Run SQLSELECT Seller_name, SUM(Quantity) AS Qty
FROM Sellers2 
LEFT OUTER JOIN Sumproduct 
ON Sellers2.City = Sumproduct.City
GROUP BY Seller_name

Con questa richiesta, abbiamo estratto l'elenco di tutti i venditori presenti nel database e calcolato l'importo totale dei beni venduti per loro in tutti i mesi. Vediamo che non ci sono vendite per il nuovo venditore Semuel Piter. Se utilizzassimo un inner join, non vedremmo il nuovo venditore, perché non ha record nella tabella Sumproduct. Possiamo anche cambiare la direzione della combinazione non solo scrivendo LEFT o RIGHT, ma anche semplicemente cambiando l'ordine delle tabelle (ovvero i due record seguenti daranno lo stesso risultato: Sellers LEFT OUTER JOIN Sumproduct e Sumproduct RIGHT OUTER JOIN Sellers).

Inoltre, alcuni DBMS consentono join esterni su un record semplificato utilizzando i segni *= e =*, che corrispondono rispettivamente a LEFT OUTER JOIN e RIGHT OUTER JOIN. Pertanto, la query precedente potrebbe essere riscritta come segue:

SELECT Seller_name, SUM(Quantity) AS Qty
FROM Sellers, Sumproduct
WHERE Sellers.City *= Sumproduct.City

Sfortunatamente MS Access non supporta un record abbreviato per un join esterno.

5. Join esterno completo (FULL OUTER JOIN)

Esiste anche un altro tipo di unione esterna: l'unione esterna completa, che visualizza tutte le righe di entrambe le tabelle e unisce solo quelle che possono essere correlate. La sintassi di un join esterno completo è la seguente:

SELECT Seller_name, Product
FROM Sellers 
FULL OUTER JOIN Sumproduct 
ON Sellers.City = Sumproduct.City

Anche in questo caso, il full external join non è supportato dai seguenti DBMS: MS Access, MySQL, SQL Server e Sybase. Come aggirare questa ingiustizia, lo considereremo nella prossima sezione.