SQL – UNION, INTERSECT, MINUS, EXCEPT – część wspólna i różnica wyników zapytań, czyli błyskawiczne wprowadzenie do operatorów zbiorowych (Set Operators)

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)

UNION (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

VN:F [1.9.22_1171]
Rating: 5.0/5 (8 votes cast)

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *