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.