W zapytaniach SQL niektórych serwerów można zastosować ciekawe operatory (tzw. operatory zbiorowe – ang. set operators) pozwalające uzyskać część wspólną lub różnicę w wynikach zapytań. Poniżej krótki przypominacz/wprowadzenie:
Wyobraźmy sobie takie 2 tabele:
Miejscowosci1:
Nazwa | Region |
---|---|
Warszawa | Centralny |
Gdańsk | Północny |
Poznań | Centralny |
Wrocław | Południowy |
Kraków | Południowy |
Miejscowosci2:
Nazwa | Region |
---|---|
Sopot | Północny |
Gdańsk | Północny |
Warszawa | Centralny |
Katowice | Południowy |
Szczecin | Zachodni |
Zadanie 1: część wspólna
Wybrać miejscowości występujące jednocześnie (część wspólna) w obu tabelach.
Przykładowe rozwiązanie dla MS SQL (i prawdopodobnie także Oracle):
SELECT Nazwa, Region FROM Miejscowosci1
INTERSECT
SELECT Nazwa, Region FROM Miejscowosci2
Silnik SQL wybierze tylko rekordy należące do części wspólnej zbiorów wybranych klauzulami SELECT.
Zadanie 2: różnica
Wybrać z tabeli Miejscowosci1 tylko miejscowości, które nie występują w tabeli Miejscowosci2
Przykładowe rozwiązanie:
(MS SQL Server)
SELECT Nazwa, Region FROM Miejscowosci1
EXCEPT
SELECT Nazwa, Region FROM Miejscowosci2
(Oracle)
SELECT Nazwa, Region FROM Miejscowosci1
MINUS
SELECT Nazwa, Region FROM Miejscowosci2
Instrukcje MINUS/EXCEPT (zależnie od dialektu) wybierają z pierwszego zestawu dane, których nie ma w drugim zestawie wybieranym klauzulą SELECT. Konstrukcja ta może być bardzo przydatna.
Zadanie 3: suma bez powtórzeń
wybrać z tabel wszystkie rekordy, bez powtórzeń
SELECT Nazwa, Region FROM Miejscowosci1
UNION
SELECT Nazwa, Region FROM Miejscowosci2
Domyślnie, klauzula UNION pominie powtarzające się wiersze – warto na to uważać.
Zadanie 4: suma z powtórzeniami
Wybrać z tabel wszystkie rekordy, niezależnie od tego, czy wartości będą się powtarzały, czy nie
SELECT Nazwa, Region FROM Miejscowosci1
UNION ALL
SELECT Nazwa, Region FROM Miejscowosci2
Mały dodatek ALL w klauzuli UNION spowoduje, że rekordy powtarzające się zostaną uwzględnione w końcowym zbiorze danych.
Trudno być może powyższe uznać za pełny poradnik, jest to raczej króciutkie wprowadzenie i zasygnalizowanie niektórych możliwości dialektów SQL’a – ale często, żeby pytać dokładniej, trzeba wiedzieć o co pytać.
Po więcej i bardziej konkretnych wskazówek odsyłam do:
EXCEPT and INTERSECT (Transact-SQL)
The UNION [ALL], INTERSECT, MINUS Operators
A do zabawy – przykładowy kod T-SQL (sprawdzony na SQL Server 2008) oparty na zmiennych tabelarycznych
DECLARE @Miejscowosci1 TABLE(Nazwa VARCHAR(100), Region VARCHAR(100))
INSERT INTO @Miejscowosci1
VALUES (’Warszawa’, 'Centralny’),
(’Gdańsk’, 'Północny’),
(’Poznań’, 'Centralny’),
(’Wrocław’, 'Południowy’),
(’Kraków’, 'Południowy’)DECLARE @Miejscowosci2 TABLE(Nazwa VARCHAR(100), Region VARCHAR(100))
INSERT INTO @Miejscowosci2
VALUES (’Sopot’, 'Północny’),
(’Gdańsk’, 'Północny’),
(’Warszawa’, 'Centralny’),
(’Katowice’, 'Południowy’),
(’Szczecin’, 'Zachodni’)–Zadanie 1: Część wspólna
SELECT Nazwa, Region FROM @Miejscowosci1
INTERSECT
SELECT Nazwa, Region FROM @Miejscowosci2–Zadanie 2: Różnica
SELECT Nazwa, Region FROM @Miejscowosci1
EXCEPT
SELECT Nazwa, Region FROM @Miejscowosci2–Zadanie 3: Wszystkie unikatowe
SELECT Nazwa, Region FROM @Miejscowosci1
UNION
SELECT Nazwa, Region FROM @Miejscowosci2–Zadanie 4: Wszystkie
SELECT Nazwa, Region FROM @Miejscowosci1
UNION ALL
SELECT Nazwa, Region FROM @Miejscowosci2