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

Leave a Comment

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *