Usare l'istruzione UNION per unire i risultati di più SELECT
Il linguaggio SQL ci offre un modo piuttosto semplice per unire, all'interno della medesima query, i risultati di due (o più) SELECT differenti.
Per ottenere tale risultato è necesario fare ricorso all'opertore UNION il quale effettuerà, appunto, l'unione dei risultati ottenuti attraverso differenti interrogazioni.
Si noti che affinchè possa essere utilizzato correttamente l'operatore UNION è necesario che:
- le query effetuino selezioni sul medesimo numero di colonne;
- le colonne richieste nelle diverse query abbiano dei tipi di dato tra loro omogenei (uguali o convertibili);
- le colonne aventi tipi di dato omogenei devono essere nel medesimo ordine in ciascuna SELECT.
Facciamo un esempio: poniamo di dover operare su un database di un'ipotetica agenzia viaggio e supponiamo che il nostro DB contenga due sole tabelle:
- hotel_italia
- nome
- stelle
- citta
- nazione
- hotel_europa
- nome
- stelle
- citta
- nazione
Ora supponiamo che un nostro cliente ci chieda di conoscere indifferentemente le offerte degli hotel sia in Italia che in Europa:
SELECT nome, stelle, citta, nazione FROM hotel_italia
UNION
SELECT nome, stelle, citta, nazione FROM hotel_europa
|
Grazie a questa query otterremo un listato completo di tutti gli Hotel presenti nelle due tabelle:
nome | stelle | citta | nazione |
Hotel Cavour | 4 | Roma | IT |
Hotel Miramare | 2 | Cattolica | IT |
Hotel Manzoni | 2 | Milano | IT |
Hotel Espana | 3 | Madrid | ES |
Hotel Hilton | 5 | Londra | UK |
Hotel am Schlossgarten | 4 | Stoccarda | DE |
Nel nostro caso i nomi dei campi delle due tabelle sono i medesimi, ma nulla vieta di unire i risultati di SELECT su tabelle aventi campi con nomi differenti; ciò che è importante, come detto, è che i campi corrispondenti abbiano il medesimo datatype, ad esempio:
SELECT nome, stelle, citta, nazione FROM hotel_italia
UNION
SELECT name AS nome, stars AS stelle, city AS citta, country AS nazione FROM hotel_europa
|
Nell'esempio qui sopra abbiamo utilizzato degli alias per la seconda query "rinominando" i campi che originariamente avevano nomi differenti nelle due tabelle.
Se non avessimo utilizzato gli alias, il motore SQL avrebbe utilizzato, all'interno del resultset, i nomi dei campi della prima query, quindi il risultato sarebbe stato il medesimo.
Rimuovere (o meno) i duplicati nelle UNION
Di default le UNION effettuano una "pulizia" del resultset dai risultati duplicati (di default opera come se fosse una SELECT DISTINCT). Qualora si desideri mostrare tutti i risultati estratti, invece, sarà necessario utilizzare UNION ALL.
Ordinare i risultati di una UNION
Una volta uniti i risultati di due o più query è possibile ordinarli utilizzando un comune ORDER BY, vediamo un esempio:
(SELECT nome, stelle, citta, nazione FROM hotel_italia)
UNION
(SELECT name AS nome, stars AS stelle, city AS citta, country AS nazione FROM hotel_europa)
ORDER BY stelle DESC, nome ASC;
|
Come potete vedere abbiamo racchiuso le due select dentro a delle parentesi tonde ed abbiamo aggiunto, al termine dell'istruzione, la clausola ORDER BY come se si trattasse di una comune SELECT.
Allo stesso modo avremmo potuto inserire delle limitazioni utilizzando la clausola LIMIT in questo modo:
(SELECT nome, stelle, citta, nazione FROM hotel_italia)
UNION
(SELECT name AS nome, stars AS stelle, city AS citta, country AS nazione FROM hotel_europa)
ORDER BY stelle DESC, nome ASC
LIMIT 10;
|
Filtrare i risultati di una UNION con la clausola WHERE
Purtroppo non è possibile applicare una WHERE ad un unione di query; per poter raggiungere un tale risultato è necessario "importare" la UNION all'interno di un'istruzione di tipo SELECT ... FROM:
SELECT * FROM (
SELECT nome, stelle, citta, nazione FROM hotel_italia
UNION
SELECT name AS nome, stars AS stelle, city AS citta, country AS nazione FROM hotel_europa
) AS temp
WHERE temp.stelle = 5;
|