sql >> Databáze >  >> RDS >> Mysql

MySQL UNION doložka

V MySQL je to UNION klauzule kombinuje výsledky z více dotazů do jediné sady výsledků.

Příklad

Předpokládejme, že máme následující tabulky:

SELECT * FROM Teachers;
SELECT * FROM Students;

Výsledek:

+-----------+-------------+
| 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        |
+-----------+-------------+

Můžeme vložit UNION klauzule mezi těmito dvěma SELECT příkazy k vrácení všech učitelů a studentů:

SELECT TeacherName FROM Teachers
UNION
SELECT StudentName FROM Students;

Výsledek:

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

Názvy sloupců jsou převzaty z prvního SELECT prohlášení.

Ve výchozím nastavení UNION klauzule implicitně aplikuje DISTINCT úkon. Jinými slovy, ve výchozím nastavení vrací pouze odlišné hodnoty. Výše uvedené výsledky tedy obsahují pouze jeden Warren, Cathy a Bill. A to i přesto, že kombinované stoly ve skutečnosti obsahují dva Warreny, dvě Cathy a tři Billy (jsou tam dva učitelé Cathy, učitel a zákazník jménem Warren a dva Bill a jeden student Bill).

Zde je příklad, který explicitně používá DISTINCT klauzule:

SELECT TeacherName FROM Teachers
UNION DISTINCT
SELECT StudentName FROM Students;

Výsledek:

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

Dostaneme tedy stejný výsledek, jaký jsme dostali bez DISTINCT doložka.

Zahrnout duplikáty

Můžeme použít ALL klíčové slovo pro zahrnutí duplicitních hodnot do výsledků:

SELECT TeacherName FROM Teachers
UNION ALL
SELECT StudentName FROM Students;

Výsledek:

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

Tentokrát jsme dostali dvanáct řádků místo osmi, které jsme dostali v našem prvním příkladu.

Vidíme, že obě Cathy byly vráceny a všechny tři účty byly vráceny.

TABLE Prohlášení

Od MySQL 8.0.19 můžeme použít UNION klauzule s TABLE prohlášení.

Zde je příklad:

TABLE Teachers
UNION
TABLE Students;

Výsledek:

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

To je ekvivalent následujícího dotazu:

SELECT * FROM Teachers
UNION
SELECT * FROM Students;

Výsledek:

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

Všimnete si, že tyto příkazy vrátí více řádků než v našem prvním příkladu dříve. Je to proto, že vybíráme všechny sloupce v tabulce, což vede k tomu, že tam, kde dříve duplikát byl, nejsou duplikáty. Zde jsou například vráceni dva učitelé jménem Bill, zatímco v předchozím příkladu byl vrácen pouze jeden. Je to proto, že TeacherId sloupce obsahují různé hodnoty, takže řádky nejsou duplicitní.

Použití ORDER BY Klauzule v Union Queries

Můžeme použít ORDER BY klauzule v každém SELECT příkazu a/nebo na kombinovaném UNION dotaz.

V každém SELECT Prohlášení

Když použijeme ORDER BY klauzule v jednotlivém SELECT příkazy v rámci UNION dotaz, musíme uzavřít každý SELECT prohlášení v závorkách:

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

Výsledek:

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

Všimněte si, že když to uděláme, ve skutečnosti to neseřadí výsledky pro výstup. Řadí výsledky pouze za účelem určení podmnožiny vybraných řádků, které se mají načíst při použití LIMIT doložka.

Proto pomocí ORDER BY bez LIMIT klauzule nemá žádný vliv na výstup.

Celkově UNION Dotaz

Můžeme také použít ORDER BY klauzule na celý dotaz, takže celý výstup je uspořádán společně.

V tomto příkladu vezmeme předchozí příklad a seřadíme kombinované výsledky:

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

Výsledek:

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

I když nepoužíváte ORDER BY klauzule v každém SELECT každý příkaz SELECT příkaz by měl být stále v závorkách a ORDER BY klauzule (nebo jakýkoli LIMIT klauzule) by měla následovat za poslední.

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

Výsledek:

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

Pamatujte, že vynechání závorek vede ke stejnému výsledku jako v případě závorek:

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

Výsledek:

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

Všimněte si, že pokud sloupec, který má být seřazen, používá alias, pak na tento sloupec musí odkazovat jeho alias (nikoli název sloupce).

Příklad:

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

Výsledek:

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

Pokud alias nepoužijeme, stane se toto:

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

Výsledek:

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

Počet sloupců

Počet sloupců vrácených každým SELECT prohlášení musí být stejné. Proto nemůžeme udělat následující:

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

Výsledek:

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

Typy dat

Vybrané sloupce jsou uvedeny na odpovídajících pozicích každého SELECT příkaz by měl mít stejný datový typ. Pokud však ne, typy a délky sloupců v UNION výsledek bere v úvahu hodnoty načtené všemi SELECT prohlášení.

Zde je to, co se stane, když se pokusíme zkombinovat TeacherName sloupec s StudentId sloupec:

SELECT TeacherName FROM Teachers
UNION
SELECT StudentId FROM Students;

Výsledek:

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

Některé jiné RDBMS by v tomto případě vytvořily chybu, ale MySQL zvládá produkovat výstup bez chyby.


  1. Vyloučení spojení:Když SQL Server odstraní nepotřebné tabulky

  2. Aktualizace verze Docker PGMASTER PostgreSQL

  3. Příklady formátování „datetimeoffset“ v SQL Server pomocí standardních formátovacích řetězců (T-SQL)

  4. ekvivalent create_series() v MySQL