Data: 14.07.2021

MS SQL łączenie wyników zapytań
Spis treści
W MS SQL Server możemy łączyć wyniki wielu zapytań w jedno zapytanie. Służą do tego operatory UNION, UNION ALL, EXCEPT i INTERSECT.
Łączenie wyników zapytań – zasady
Aby możliwe było złączenie wyników zapytań, muszą zostać spełnione następujące warunki:
- łączone wyniki zapytań muszą składać się z takiej samej liczby kolumn
- odpowiadające sobie kolumny w łączonych zapytaniach muszą być tych samych typów lub muszą umożliwiać niejawną konwersję typów.
W przypadku niejawnej konwersji, SQL Server sam „zmienia” typ danych.
Nie dla każdej kolumny możliwe jest dokonanie jawnej lub niejawnej, konwersji typu.
Przykład
-- dodajemy dwie liczby. Wynik 4SELECT 2 + 2;
-- dodajemy tekst (w apostrofach) i liczbę.-- Niejawna konwersja tekstu na liczbę. Wynik 4.SELECT '2'+ 2;
-- dodajemy dwa teksty. Wynik 22.SELECT '2' + '2';Przykład
W poniższym przykładzie:
- typ kolumny EmployeeID w tabeli A jest określony jako INTEGER a w tabeli B jako Varchar. W jednej i drugiej tabeli w kolumnie EmployeeID przechowywane są liczby. Możliwa jest zarówno jawna jak i niejawna konwersja typu zarówno na VARCHAR jak i na INTEGER.
- typ kolumny CustomerID w tabeli A jest określony jako VARCHAR a w tabeli B jako INTEGER. W tabeli A w kolumnie CustomerID przechowywane są teksty. W tabeli B natomiast przechowywane są liczby. Nie jest możliwa konwersja typu kolumny CustomerID w tabeli A na INTEGER.

Wyniki zapytań możemy łączyć za pomocą poniższych operatorów:
- UNION lub UNION ALL
- INTERSECT
- EXCEPT

Operatory UNION, UNION ALL
Za pomocą operatorów UNION lub UNION ALL dodajemy do siebie wyniki zapytań. Odpowiadają one operatorowi sumy zbiorów.
Operator UNION eliminuje ze złączonych wyników zapytań duplikaty.
Operator UNION ALL nie eliminuje duplikatów.
Przykład
W poniższym przykładzie:
- w pierwszym zapytaniu otrzymamy ID i nazwę produktu z tabeli dbo.Products znajdującej się w bazie Nortwhind
- w drugim zapytaniu otrzymamy ID i nazwę produktu z tabeli Production.Product znajdującej się w bazie AdventureWorks2012
- łączymy obydwa wyniki zapytań za pomocą operatora UNION. W wyniku otrzymamy jedynie unikalne rekordy odczytane za pomocą obydwu zapytań. Powtarzające się rekordy zostaną wyeliminowane.
SELECT ProductID, ProductNameFROM Northwind.dbo.ProductsUNIONSELECT ProductID, NameFROM AdventureWorks2012.Production.Product;Przykład
Za pomocą poniższego zapytania:
- otrzymamy ID i nazwę produktu z tabeli dbo.Products znajdującej się w bazie Nortwhind
- otrzymamy ID i nazwę produktu z tabeli Production.Product znajdującej się w bazie AdventureWorks2012
- łączymy obydwa wyniki zapytań za pomocą operatora UNION ALL. W wyniku otrzymamy wszystkie rekordy odczytane za pomocą obydwu zapytań.
SELECT ProductID, ProductNameFROM Northwind.dbo.ProductsUNION ALLSELECT ProductID, NameFROM AdventureWorks2012.Production.Product;Operatory UNION i UNION ALL są symetryczne — zmiana kolejności zapytań nie spowoduje zmiany wyniku.
Operatory UNION i UNION ALL versus operator OR
Operatory UNION i UNION ALL pozwalają dodać wiersze do wyniku zapytania na takiej samej zasadzie, jak robi to operator logiczny OR.
Przykład
W poniższym zapytaniu otrzymamy ID i nazwę dla tych produktów, w przypadku których cena jednostkowa (UnitPrice) jest między 30,00 a 50,00 oraz między 70,00 a 90,00.
SELECT ProductID, ProductNameFROM Northwind.dbo.ProductsWHERE UnitPrice BETWEEN 30.00 AND 50.00OR UnitPrice BETWEEN 70.00 AND 90.00;Każdy z powyższych warunków logicznych możemy umieścić w odrębnym zapytaniu i połączyć ich wyniki za pomocą operatora UNION ALL:
SELECT ProductID, ProductNameFROM Northwind.dbo.ProductsWHERE UnitPrice BETWEEN 30.00 AND 50.00UNION ALLSELECT ProductID, ProductNameFROM Northwind.dbo.ProductsWHERE UnitPrice BETWEEN 70.00 AND 90.00;Operator INTERSECT
Operator INTERSECT zwraca część wspólną wyników dwóch zapytań. W wyniku jego działania otrzymamy tylko te rekordy, które zostały zwrócone przez obydwa zapytania.
Przykład
W wyniku poniższego zapytania otrzymamy tylko te nazwy miast, które występują zarówno w tabeli Customers, jak i w tabeli Employees. Możemy się zatem dowiedzieć, czy są miasta, w których mieszkają i klienci, i pracownicy.
SELECT CityFROM CustomersINTERSECTSELECT CityFROM Employees;Operator INTERSECT jest symetryczny — zmiana kolejności zapytań nie spowoduje zmiany wyniku.
Operator EXCEPT
Operator EXCEPT zwraca te rekordy, które znalazły się wyłącznie w wyniku pierwszego zapytania. W wyniku otrzymamy więc te rekordy, które zostały zwrócone przez pierwsze zapytanie, ale nie było ich w drugim zapytaniu.
W wyniku poniższego zapytania otrzymamy tylko te produkty, które są w bazie Northwind w tabeli Products, ale nie ma ich w bazie AdventureWorks2012 w tabeli Production.Product.
SELECT ProductID, ProductNameFROM Northwind.dbo.ProductsEXCEPTSELECT ProductID, NameFROM AdventureWorks2012.Production.Product;Operator EXCEPT jest asymetryczny — zmiana kolejności zapytań spowoduje zmianę wyniku.
Sortowanie złączonych zapytań
Poniższe zapytania zostały złączone ze sobą i SQL Server traktuje je jak jedno zapytanie. W związku z tym, aby posortować wynik, klauzulę ORDER BY umieszczamy na końcu całego zapytania.
Średnik również umieszczamy jedynie na końcu drugiego zapytania.
SELECT ProductID, ProductNameFROM Northwind.dbo.ProductsUNION ALLSELECT ProductID, NameFROM AdventureWorks2012.Production.ProductORDER BY ProductName;
Nazwy kolumn złączonych wyników zapytań nie muszą być takie same. Po złączeniu, w wyniku są nazwy kolumn z pierwszego zapytania i tylko ich możemy użyć do sortowania. Nie możemy użyć do sortowania nazw kolumn z drugiego i z kolejnych złączonych zapytań.
W klauzuli ORDER BY możemy użyć numerów kolumn zamiast nazw.
SELECT ProductID, ProductNameFROM Northwind.dbo.ProductsUNION ALLSELECT ProductID, NameFROM AdventureWorks2012.Production.ProductORDER BY 2;Jeśli w klauzuli ORDER BY używamy numerów kolumn, zmiana kolejności kolumn w tabeli może wpłynąć na wynik naszego zapytania. Sytuacja taka będzie miała miejsce, jeśli kolumna, której użyliśmy do sortowania zmieni swoją kolejność.
