Database
 sql >> Database >  >> RDS >> Database

Clausola SQL UNION per principianti

In SQL, il UNION La clausola concatena i risultati di due query in un unico set di risultati.

Puoi usare il UNION clausola con o senza ALL argomento:

  • UNION ALL – Include duplicati.
  • UNION – Esclude i duplicati.

Di seguito sono riportati alcuni esempi di base per dimostrare come funziona.

Tabelle di esempio

Supponiamo di avere due tabelle:Cats e Dogs

Cats

+---------+-----------+
| CatId   | CatName   |
|---------+-----------|
| 1       | Meow      |
| 2       | Fluffy    |
| 3       | Scratch   |
+---------+-----------+

Dogs

+---------+-----------+
| DogId   | DogName   |
|---------+-----------|
| 1       | Fetch     |
| 2       | Fluffy    |
| 3       | Wag       |
| 1002    | Fetch     |
+---------+-----------+

Possiamo usare un SELECT dichiarazione con un UNION clausola per combinare i risultati di entrambe le tabelle in un unico set di risultati.

Esempio di utilizzo di UNION ALL

Per prima cosa, utilizziamo UNION ALL in modo che includa duplicati.

SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats;

Risultato:

+-----------+
| PetName   |
|-----------|
| Fetch     |
| Fluffy    |
| Wag       |
| Fetch     |
| Meow      |
| Fluffy    |
| Scratch   |
+-----------+
(7 rows affected)

In questo caso vengono restituite sette righe. Possiamo vedere che "Fetch" viene restituito due volte. Questo perché ci sono due cani di nome Fetch.

Ci sono anche un gatto e un cane con lo stesso nome:Fluffy.

Si noti che ho utilizzato un alias di colonna per denominare il campo restituito dall'operazione. Se non l'avessi fatto, il risultato avrebbe utilizzato i nomi delle colonne della prima query. In tal caso, l'intestazione della colonna sarebbe stata chiamata DogName invece di PetName .

SELECT DogName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats;

Risultato:

+-----------+
| DogName   |
|-----------|
| Fetch     |
| Fluffy    |
| Wag       |
| Fetch     |
| Meow      |
| Fluffy    |
| Scratch   |
+-----------+
(7 rows affected)

Questo potrebbe essere accettabile o meno, a seconda dei dati che stai restituendo nella tua query. Nel nostro caso, non è appropriato, perché non tutti i risultati sono cani.

Esempio di utilizzo di UNION

Vediamo cosa succede quando rimuoviamo ALL argomento.

SELECT DogName AS PetName
FROM Dogs
UNION
SELECT CatName
FROM Cats;

Risultato:

+-----------+
| PetName   |
|-----------|
| Fetch     |
| Fluffy    |
| Meow      |
| Scratch   |
| Wag       |
+-----------+
(5 rows affected)

Questa volta vengono restituite solo cinque righe. Entrambi i duplicati vengono rimossi.

UNION vs DISTINCT

Nota che questo è diverso dall'applicazione di DISTINCT a ogni singolo SELECT dichiarazione. Se lo avessimo fatto, Fluffy sarebbe stato restituito due volte, perché ALL si applicherebbe solo per il SELECT dichiarazione contro cui viene applicato (non ai risultati concatenati).

Ecco un esempio per illustrare cosa intendo.

SELECT DISTINCT DogName AS PetName
FROM Dogs
UNION ALL
SELECT DISTINCT CatName
FROM Cats;

Risultato:

+-----------+
| PetName   |
|-----------|
| Fetch     |
| Fluffy    |
| Wag       |
| Fluffy    |
| Meow      |
| Scratch   |
+-----------+
(6 rows affected)

Tutte le query devono restituire lo stesso numero di colonne

Quando usi UNION clausola, ogni query deve avere lo stesso numero di colonne e devono trovarsi nello stesso ordine.

In caso contrario, riceverai un errore.

SELECT CatName FROM Cats
UNION ALL
SELECT DogId, DogName FROM Dogs;

Risultato:

Msg 205, Level 16, State 1, Line 1
All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.

Questo è l'errore restituito da SQL Server quando si utilizza un numero di colonne diverso. Questo particolare errore indica che la stessa restrizione si applica anche a INTERSECT e EXCEPT operatori. Il messaggio di errore che ricevi potrebbe essere diverso, a seconda del tuo DBMS.

I tipi di dati devono essere compatibili

Oltre a richiedere lo stesso numero di colonne, tali colonne devono avere un tipo di dati compatibile.

Non devono necessariamente essere dello stesso tipo di dati, ma dovranno essere compatibili. Cioè, devono essere compatibili tramite la conversione implicita. Se i tipi di dati non corrispondono, il DBMS deve essere in grado di eseguire una conversione implicita in modo che corrispondano.

In caso contrario, riceverai un errore.

SELECT CatName FROM Cats
UNION ALL
SELECT DogId FROM Dogs;

Risultato:

Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the varchar value 'Meow' to data type int.

Ordinare i risultati

Se vuoi ordinare i risultati con il ORDER BY clausola, dovrai inserirla nell'ultima query. Non puoi inserire un ORDER BY separato clausola su ogni query, o del resto, qualsiasi query che non sia l'ultima.

Ecco l'errore che ottengo quando provo a farlo in SQL Server:

SELECT DogName AS PetName
FROM Dogs
ORDER BY DogName
UNION ALL
SELECT CatName
FROM Cats;

Risultato:

Msg 156, Level 15, State 1, Line 4
Incorrect syntax near the keyword 'UNION'.

Pertanto, se vogliamo ordinare i risultati, dovremo fare qualcosa del genere:

SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats
ORDER BY PetName;

Applicazione di UNION a Più di due Query

Gli esempi precedenti hanno combinato i risultati di due diverse query, ma non c'è nulla che ti impedisca di aggiungerne altre. Puoi usarlo per combinare i risultati di molte query, se necessario.

Ad esempio, se avessimo anche un Birds tabella, potremmo farlo:

SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats
UNION ALL
SELECT BirdName
FROM Birds;

Normalizzazione

Gli esempi in questa pagina mettono cani e gatti in due tabelle separate. Il motivo per cui l'ho fatto è perché è un modo chiaro e conciso per illustrare come UNION funziona.

In pratica, potresti averli nella stessa tabella chiamata, ad esempio Pets , quindi avere un PetTypes separato tabella (o simile). Questo è noto come normalizzazione ed è il modo in cui vengono generalmente progettati i database relazionali.

È quindi possibile eseguire un join su queste tabelle per restituire i dati come richiesto.