W SQL UNION
klauzula łączy wyniki dwóch zapytań w jeden zestaw wyników.
Możesz użyć UNION
klauzula z lub bez ALL
argument:
UNION ALL
– Zawiera duplikaty.UNION
– Wyklucza duplikaty.
Poniżej znajduje się kilka podstawowych przykładów pokazujących, jak to działa.
Przykładowe tabele
Załóżmy, że mamy dwie tabele:Cats
i Dogs
Cats
+---------+-----------+ | CatId | CatName | |---------+-----------| | 1 | Meow | | 2 | Fluffy | | 3 | Scratch | +---------+-----------+
Dogs
+---------+-----------+ | DogId | DogName | |---------+-----------| | 1 | Fetch | | 2 | Fluffy | | 3 | Wag | | 1002 | Fetch | +---------+-----------+
Możemy użyć SELECT
oświadczenie z UNION
klauzula łącząca wyniki z obu tabel w jeden zestaw wyników.
Przykład użycia UNION ALL
Najpierw użyjmy UNION ALL
tak, że zawiera duplikaty.
SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats;
Wynik:
+-----------+ | PetName | |-----------| | Fetch | | Fluffy | | Wag | | Fetch | | Meow | | Fluffy | | Scratch | +-----------+ (7 rows affected)
W takim przypadku zwracanych jest siedem wierszy. Widzimy, że „Fetch” jest zwracane dwukrotnie. Dzieje się tak, ponieważ istnieją dwa psy o imieniu Fetch.
Jest też kot i pies o tym samym imieniu:Fluffy.
Zauważ, że użyłem aliasu kolumny, aby nazwać pole zwrócone przez operację. Gdybym tego nie zrobił, wynik użyłby nazw kolumn z pierwszego zapytania. W takim przypadku nagłówek kolumny miałby nazwę DogName
zamiast PetName
.
SELECT DogName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats;
Wynik:
+-----------+ | DogName | |-----------| | Fetch | | Fluffy | | Wag | | Fetch | | Meow | | Fluffy | | Scratch | +-----------+ (7 rows affected)
Może to być dopuszczalne lub nie, w zależności od danych, które zwracasz w zapytaniu. W naszym przypadku nie jest to właściwe, ponieważ nie wszystkie wyniki dotyczą psów.
Przykład użycia UNION
Zobaczmy, co się stanie, gdy usuniemy ALL
argument.
SELECT DogName AS PetName
FROM Dogs
UNION
SELECT CatName
FROM Cats;
Wynik:
+-----------+ | PetName | |-----------| | Fetch | | Fluffy | | Meow | | Scratch | | Wag | +-----------+ (5 rows affected)
Tym razem zwracanych jest tylko pięć wierszy. Oba duplikaty są usuwane.
UNION
vs DISTINCT
Zauważ, że różni się to od stosowania DISTINCT
do każdego z osobna SELECT
oświadczenie. Gdybyśmy to zrobili, Fluffy zostałby zwrócony dwa razy, ponieważ ALL
dotyczy tylko SELECT
oświadczenie, że jest stosowany przeciwko (nie do połączonych wyników).
Oto przykład ilustrujący, o co mi chodzi.
SELECT DISTINCT DogName AS PetName
FROM Dogs
UNION ALL
SELECT DISTINCT CatName
FROM Cats;
Wynik:
+-----------+ | PetName | |-----------| | Fetch | | Fluffy | | Wag | | Fluffy | | Meow | | Scratch | +-----------+ (6 rows affected)
Wszystkie zapytania muszą zwracać tę samą liczbę kolumn
Kiedy używasz UNION
klauzula, każde zapytanie musi mieć taką samą liczbę kolumn i muszą one być w tej samej kolejności.
Jeśli nie, pojawi się błąd.
SELECT CatName FROM Cats
UNION ALL
SELECT DogId, DogName FROM Dogs;
Wynik:
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 jest błąd, który SQL Server zwraca, gdy używa nierównej liczby kolumn. Ten konkretny błąd wskazuje, że to samo ograniczenie dotyczy również INTERSECT
i EXCEPT
operatorów. Otrzymany komunikat o błędzie może się różnić w zależności od systemu DBMS.
Typy danych muszą być zgodne
Oprócz wymagania takiej samej liczby kolumn, te kolumny muszą mieć zgodny typ danych.
Niekoniecznie muszą to być dane tego samego typu, ale muszą być kompatybilne. Oznacza to, że muszą być kompatybilne poprzez niejawną konwersję. Jeśli typy danych nie są zgodne, DBMS musi być w stanie wykonać niejawną konwersję, aby były zgodne.
Jeśli nie, pojawi się błąd.
SELECT CatName FROM Cats
UNION ALL
SELECT DogId FROM Dogs;
Wynik:
Msg 245, Level 16, State 1, Line 1 Conversion failed when converting the varchar value 'Meow' to data type int.
Porządkowanie wyników
Jeśli chcesz posortować wyniki za pomocą ORDER BY
klauzula, musisz umieścić ją w ostatnim zapytaniu. Nie możesz umieścić oddzielnego ORDER BY
klauzula w każdym zapytaniu lub w każdym zapytaniu, które nie jest ostatnim.
Oto błąd, który pojawia się, gdy próbuję to zrobić w SQL Server:
SELECT DogName AS PetName
FROM Dogs
ORDER BY DogName
UNION ALL
SELECT CatName
FROM Cats;
Wynik:
Msg 156, Level 15, State 1, Line 4 Incorrect syntax near the keyword 'UNION'.
Dlatego jeśli chcemy uporządkować wyniki, musimy zrobić coś takiego:
SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats
ORDER BY PetName;
Stosowanie UNION
do Więcej niż dwóch zapytań
Poprzednie przykłady łączyły wyniki z dwóch różnych zapytań, ale nic nie stoi na przeszkodzie, aby dodać więcej. W razie potrzeby możesz go użyć do połączenia wyników wielu zapytań.
Na przykład, gdybyśmy mieli również Birds
tabeli, możemy to zrobić:
SELECT DogName AS PetName
FROM Dogs
UNION ALL
SELECT CatName
FROM Cats
UNION ALL
SELECT BirdName
FROM Birds;
Normalizacja
Przykłady na tej stronie umieszczają koty i psy w dwóch oddzielnych tabelach. Powodem, dla którego to zrobiłem, jest to, że jest to jasny i zwięzły sposób na zilustrowanie, jak UNION
działa.
W praktyce możesz mieć je w tej samej tabeli o nazwie, powiedzmy Pets
, a następnie przygotuj oddzielne PetTypes
stół (lub podobny). Nazywa się to normalizacją i jest to sposób, w jaki zwykle projektuje się relacyjne bazy danych.
Następnie możesz uruchomić sprzężenie w tych tabelach, aby zwrócić dane zgodnie z wymaganiami.