sql >> Databáze >  >> RDS >> Database

SQL UNION doložka pro začátečníky

V SQL, UNION klauzule zřetězí výsledky dvou dotazů do jediné sady výsledků.

Můžete použít UNION klauzule s nebo bez ALL argument:

  • UNION ALL – Zahrnuje duplikáty.
  • UNION – Nezahrnuje duplikáty.

Níže je uvedeno několik základních příkladů, které demonstrují, jak to funguje.

Ukázkové tabulky

Předpokládejme, že máme dvě tabulky:Cats a Dogs

Cats

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

Dogs

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

Můžeme použít SELECT příkaz s UNION klauzule pro spojení výsledků z obou tabulek do jedné sady výsledků.

Příklad pomocí UNION ALL

Nejprve použijeme UNION ALL tak, aby obsahoval duplikáty.

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

Výsledek:

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

V tomto případě se vrátí sedm řádků. Vidíme, že „Načíst“ je vráceno dvakrát. Je to proto, že existují dva psi jménem Fetch.

Je tu také kočka a pes se stejným jménem:Fluffy.

Všimněte si, že jsem k pojmenování pole vráceného operací použil alias sloupce. Pokud bych to neudělal, výsledek by použil názvy sloupců z prvního dotazu. V takovém případě by se záhlaví sloupce jmenovalo DogName místo PetName .

SELECT DogName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats;

Výsledek:

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

To může nebo nemusí být přijatelné v závislosti na datech, která vracíte ve svém dotazu. V našem případě to není vhodné, protože ne všechny výsledky jsou psi.

Příklad pomocí UNION

Podívejme se, co se stane, když odstraníme ALL argument.

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

Výsledek:

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

Tentokrát je vráceno pouze pět řádků. Oba duplikáty jsou odstraněny.

UNION vs DISTINCT

Všimněte si, že se to liší od použití DISTINCT každému jednotlivému SELECT prohlášení. Pokud bychom to udělali, Fluffy by byl vrácen dvakrát, protože ALL platí pouze pro SELECT prohlášení, proti kterému je aplikováno (nikoli na zřetězené výsledky).

Zde je příklad pro ilustraci toho, co mám na mysli.

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

Výsledek:

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

Všechny dotazy musí vrátit stejný počet sloupců

Když použijete UNION klauzule, každý dotaz musí mít stejný počet sloupců a musí být ve stejném pořadí.

Pokud ne, zobrazí se chyba.

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

Výsledek:

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.

To je chyba, kterou SQL Server vrací při použití nestejného počtu sloupců. Tato konkrétní chyba znamená, že stejné omezení platí také pro INTERSECT a EXCEPT operátory. Chybová zpráva, kterou obdržíte, se může lišit v závislosti na vašem DBMS.

Typy dat musí být kompatibilní

Kromě požadavku na stejný počet sloupců musí mít tyto sloupce kompatibilní datový typ.

Nemusí nutně jít o stejný datový typ, ale musí být kompatibilní. To znamená, že musí být kompatibilní prostřednictvím implicitní konverze. Pokud se datové typy neshodují, musí být DBMS schopen provést implicitní konverzi, aby se shodovaly.

Pokud ne, zobrazí se chyba.

SELECT CatName FROM Cats
UNION ALL
SELECT DogId FROM Dogs;

Výsledek:

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

Pořadí výsledků

Pokud chcete výsledky seřadit pomocí ORDER BY klauzule, budete ji muset vložit do posledního dotazu. Nemůžete vložit samostatný ORDER BY klauzule na každý dotaz, nebo v tomto případě jakýkoli dotaz, který není posledním.

Zde je chyba, kterou dostávám, když se to pokouším udělat na serveru SQL:

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

Výsledek:

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

Pokud tedy chceme seřadit výsledky, budeme muset udělat něco takového:

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

Použití UNION na Více než dva dotazy

Předchozí příklady zkombinovaly výsledky ze dvou různých dotazů, ale nic vám nebrání přidat další. V případě potřeby jej můžete použít ke spojení výsledků mnoha dotazů.

Pokud bychom například měli také Birds stůl, mohli bychom udělat toto:

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

Normalizace

Příklady na této stránce rozdělují kočky a psy do dvou samostatných tabulek. Důvod, proč jsem to udělal, je ten, že je to jasný a stručný způsob, jak ilustrovat, jak UNION funguje.

V praxi je můžete mít ve stejné tabulce s názvem, řekněme Pets , pak mít samostatný PetTypes stůl (nebo podobný). Toto je známé jako normalizace a je to způsob, jakým jsou obvykle navrhovány relační databáze.

Poté můžete spustit spojení na těchto tabulkách a vrátit data podle potřeby.


  1. Převeďte časové razítko Unixu na člověkem čitelné datum pomocí MySQL

  2. Výkon SQL:WHERE vs. WHERE (ROW_NUMBER)

  3. Chyba SQL s neplatným názvem sloupce

  4. Spojte frázi končící na předponu s fulltextovým vyhledáváním