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

Clausola MySQL UNION

In MySQL, il UNION La clausola combina i risultati di più query in un unico set di risultati.

Esempio

Supponiamo di avere le seguenti tabelle:

SELECT * FROM Teachers;
SELECT * FROM Students;

Risultato:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         1 | Warren      |
|         2 | Ben         |
|         3 | Cathy       |
|         4 | Cathy       |
|         5 | Bill        |
|         6 | Bill        |
+-----------+-------------+

+-----------+-------------+
| StudentId | StudentName |
+-----------+-------------+
|         1 | Faye        |
|         2 | Jet         |
|         3 | Spike       |
|         4 | Ein         |
|         5 | Warren      |
|         6 | Bill        |
+-----------+-------------+

Possiamo inserire il UNION clausola tra questi due SELECT dichiarazioni da restituire a tutti gli insegnanti e gli studenti:

SELECT TeacherName FROM Teachers
UNION
SELECT StudentName FROM Students;

Risultato:

+-------------+
| TeacherName |
+-------------+
| Warren      |
| Ben         |
| Cathy       |
| Bill        |
| Faye        |
| Jet         |
| Spike       |
| Ein         |
+-------------+

I nomi delle colonne sono presi dal primo SELECT dichiarazione.

Per impostazione predefinita, il UNION La clausola applica implicitamente un DISTINCT operazione. In altre parole, restituisce solo valori distinti per impostazione predefinita. Quindi i risultati di cui sopra contengono solo uno ciascuno di Warren, Cathy e Bill. Questo nonostante il fatto che le tabelle combinate contengano effettivamente due Warren, due Cathy e tre Bill (ci sono due insegnanti chiamate Cathy, un'insegnante e un cliente chiamato Warren, e due chiamate Bill, oltre a uno studente chiamato Bill).

Ecco un esempio che utilizza esplicitamente il DISTINCT clausola:

SELECT TeacherName FROM Teachers
UNION DISTINCT
SELECT StudentName FROM Students;

Risultato:

+-------------+
| TeacherName |
+-------------+
| Warren      |
| Ben         |
| Cathy       |
| Bill        |
| Faye        |
| Jet         |
| Spike       |
| Ein         |
+-------------+

Quindi otteniamo lo stesso risultato che abbiamo ottenuto senza DISTINCT clausola.

Includi duplicati

Possiamo usare il ALL parola chiave per includere valori duplicati nei risultati:

SELECT TeacherName FROM Teachers
UNION ALL
SELECT StudentName FROM Students;

Risultato:

+-------------+
| TeacherName |
+-------------+
| Warren      |
| Ben         |
| Cathy       |
| Cathy       |
| Bill        |
| Bill        |
| Faye        |
| Jet         |
| Spike       |
| Ein         |
| Warren      |
| Bill        |
+-------------+

Questa volta abbiamo ottenuto dodici righe invece delle otto che abbiamo ottenuto nel nostro primo esempio.

Possiamo vedere che entrambi i Cathy sono stati restituiti e tutti e tre i Bill sono stati restituiti.

TABLE Dichiarazioni

Da MySQL 8.0.19 possiamo usare UNION clausola con la TABLE dichiarazione.

Ecco un esempio:

TABLE Teachers
UNION
TABLE Students;

Risultato:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         1 | Warren      |
|         2 | Ben         |
|         3 | Cathy       |
|         4 | Cathy       |
|         5 | Bill        |
|         6 | Bill        |
|         1 | Faye        |
|         2 | Jet         |
|         3 | Spike       |
|         4 | Ein         |
|         5 | Warren      |
+-----------+-------------+

È l'equivalente della seguente query:

SELECT * FROM Teachers
UNION
SELECT * FROM Students;

Risultato:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         1 | Warren      |
|         2 | Ben         |
|         3 | Cathy       |
|         4 | Cathy       |
|         5 | Bill        |
|         6 | Bill        |
|         1 | Faye        |
|         2 | Jet         |
|         3 | Spike       |
|         4 | Ein         |
|         5 | Warren      |
+-----------+-------------+

Noterai che queste istruzioni restituiscono più righe rispetto al nostro primo esempio precedente. Questo perché stiamo selezionando tutte le colonne nella tabella, il che si traduce in non duplicati dove in precedenza c'era un duplicato. Ad esempio, qui vengono restituiti due insegnanti chiamati Bill mentre solo uno è stato restituito nell'esempio precedente. Questo perché TeacherId le colonne contengono valori diversi, quindi le righe non sono duplicate.

Utilizzo di ORDER BY Clausola in Union Query

Possiamo usare il ORDER BY clausola in ogni SELECT dichiarazione e/o sul combinato UNION interrogazione.

In ogni SELECT Dichiarazione

Quando utilizziamo il ORDER BY clausola nella singola SELECT dichiarazioni all'interno di una UNION query, dobbiamo racchiudere ogni SELECT affermazione tra parentesi:

(SELECT * FROM Teachers ORDER BY TeacherName ASC LIMIT 2)
UNION
(SELECT * FROM Students ORDER BY StudentName ASC LIMIT 2);

Risultato:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         2 | Ben         |
|         5 | Bill        |
|         6 | Bill        |
|         4 | Ein         |
+-----------+-------------+

Nota che quando lo facciamo, in realtà non ordina i risultati per l'output. Ordina i risultati solo allo scopo di determinare il sottoinsieme delle righe selezionate da recuperare quando si applica il LIMIT clausola.

Pertanto, utilizzando ORDER BY senza il LIMIT clausola non ha alcun effetto sull'output.

Nel complesso UNION Interroga

Possiamo anche usare un ORDER BY clausola sull'intera query, in modo che l'intero output sia ordinato insieme.

In questo esempio, prendiamo l'esempio precedente e ordiniamo i risultati combinati:

(SELECT * FROM Teachers ORDER BY TeacherName ASC LIMIT 2)
UNION
(SELECT * FROM Students ORDER BY StudentName ASC LIMIT 2)
ORDER BY TeacherName DESC;

Risultato:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         4 | Ein         |
|         5 | Bill        |
|         6 | Bill        |
|         2 | Ben         |
+-----------+-------------+

Anche quando non si utilizza il ORDER BY clausola all'interno di ogni SELECT istruzione, ogni SELECT l'istruzione dovrebbe essere ancora tra parentesi e ORDER BY clausola (o qualsiasi LIMIT clausola) dovrebbe essere dopo l'ultima.

(SELECT * FROM Teachers)
UNION
(SELECT * FROM Students)
ORDER BY TeacherName ASC;

Risultato:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         2 | Ben         |
|         5 | Bill        |
|         6 | Bill        |
|         3 | Cathy       |
|         4 | Cathy       |
|         4 | Ein         |
|         1 | Faye        |
|         2 | Jet         |
|         3 | Spike       |
|         1 | Warren      |
|         5 | Warren      |
+-----------+-------------+

Intendiamoci, l'omissione delle parentesi produce lo stesso risultato di quella con le parentesi:

SELECT * FROM Teachers
UNION
SELECT * FROM Students
ORDER BY TeacherName ASC;

Risultato:

+-----------+-------------+
| TeacherId | TeacherName |
+-----------+-------------+
|         2 | Ben         |
|         5 | Bill        |
|         6 | Bill        |
|         3 | Cathy       |
|         4 | Cathy       |
|         4 | Ein         |
|         1 | Faye        |
|         2 | Jet         |
|         3 | Spike       |
|         1 | Warren      |
|         5 | Warren      |
+-----------+-------------+

Tieni presente che se una colonna da ordinare utilizza un alias, è necessario fare riferimento a tale colonna tramite il suo alias (non il nome della colonna).

Esempio:

(SELECT TeacherName t FROM Teachers)
UNION
(SELECT StudentName FROM Students)
ORDER BY t ASC;

Risultato:

+--------+
| t      |
+--------+
| Ben    |
| Bill   |
| Cathy  |
| Ein    |
| Faye   |
| Jet    |
| Spike  |
| Warren |
+--------+

Ecco cosa succede se non utilizziamo l'alias:

(SELECT TeacherName t FROM Teachers)
UNION
(SELECT StudentName FROM Students)
ORDER BY TeacherName ASC;

Risultato:

ERROR 1054 (42S22): Unknown column 'TeacherName' in 'order clause'

Numero di colonne

Il numero di colonne restituite da ogni SELECT l'affermazione deve essere la stessa Pertanto, non possiamo fare quanto segue:

SELECT TeacherName FROM Teachers
UNION
SELECT StudentId, StudentName FROM Students;

Risultato:

ERROR 1222 (21000): The used SELECT statements have a different number of columns

Tipi di dati

Colonne selezionate elencate nelle posizioni corrispondenti di ogni SELECT l'istruzione dovrebbe avere lo stesso tipo di dati. Tuttavia, in caso contrario, i tipi e le lunghezze delle colonne in UNION risultato tiene conto dei valori recuperati da tutti i SELECT dichiarazioni.

Ecco cosa succede se proviamo a combinare il TeacherName colonna con StudentId colonna:

SELECT TeacherName FROM Teachers
UNION
SELECT StudentId FROM Students;

Risultato:

+-------------+
| TeacherName |
+-------------+
| Warren      |
| Ben         |
| Cathy       |
| Bill        |
| 1           |
| 2           |
| 3           |
| 4           |
| 5           |
| 6           |
+-------------+

Alcuni altri RDBMS produrrebbero un errore in questo caso, ma MySQL riesce a produrre un output senza errori.