Data: 14.07.2021

Łączenie wyników zapytań w MS SQL Server

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 4
SELECT 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.

Title

Wyniki zapytań możemy łączyć za pomocą poniższych operatorów:

  • UNION lub UNION ALL
  • INTERSECT
  • EXCEPT

Title

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, ProductName
FROM Northwind.dbo.Products
UNION
SELECT ProductID, Name
FROM 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, ProductName
FROM Northwind.dbo.Products
UNION ALL
SELECT ProductID, Name
FROM 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, ProductName
FROM Northwind.dbo.Products
WHERE UnitPrice BETWEEN 30.00 AND 50.00
OR 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, ProductName
FROM Northwind.dbo.Products
WHERE UnitPrice BETWEEN 30.00 AND 50.00
UNION ALL
SELECT ProductID, ProductName
FROM Northwind.dbo.Products
WHERE 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 City
FROM Customers
INTERSECT
SELECT City
FROM 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, ProductName
FROM Northwind.dbo.Products
EXCEPT
SELECT ProductID, Name
FROM 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, ProductName
FROM Northwind.dbo.Products
UNION ALL
SELECT ProductID, Name
FROM AdventureWorks2012.Production.Product
ORDER BY ProductName;

Title

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, ProductName
FROM Northwind.dbo.Products
UNION ALL
SELECT ProductID, Name
FROM AdventureWorks2012.Production.Product
ORDER 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ść.

Tomasz Majewski
Tomasz Majewski
Programista C#, Python, VBA
Udostępnij wpis:udostępnij Facebookudostępnij Linkedinudostępnij e-mail

Polecane