Если объединения используются в SQL для слияния полей двух источников, то ключевые слова UNION
, INTERSECT
и EXCEPT
сравнивают значения полей в двух наборах и строят новый итоговый набор на основании результатов сравнения. Каждое из перечисленных ключевых слов может использоваться в конце синтаксически правильного запроса SQL, а за ним может следовать второй запрос; в этом случае итоговые наборы двух запросов сравниваются и записи либо включаются в результат, либо игнорируются.
Сравниваемые наборы данных должны содержать одинаковое количество полей, относящихся к соответствующим типам. При этом не требуется, чтобы поля имели одинаковые имена или принадлежали к одной таблице или источнику данных.
UNION
. Все различающиеся записи двух наборов включаются в один набор данных. Совпадающие записи не дублируются.
INTERSECT
. Все записи, не входящие в оба набора данных, игнорируются. Таким образом, результат состоит только из записей, присутствующих в обоих наборах.
EXCEPT
. Все записи, входящие в оба набора данных, игнорируются. Таким образом, результат состоит только из тех записей набора, указанного слева от ключевого слова EXCEPT
, которые не входят в набор, указанный справа от него.
В листингах ниже показаны результаты применения этих операций к двум наборам данных. В листинге 33 итоговый набор формируется слиянием фамилий авторов с названиями книг, для чего используется ключевое слово UNION
.
В листинге 34 продемонстрирована выборка кодов ISBN
из таблицы editions
. Выборка ограничивается записями, которые упоминаются более чем в двух поставках в таблице shipments
. Наконец, в листинге 35 из первого запроса исключаются все записи, входящие во второй запрос.
booktown=# SELECT title FROM books UNION
SELECT lastname FROM authors
LIMIT 11;
title
2001: A Space Odyssey Alcott
Bartholomew and the Oobleck
Bianco
Bourgeois
Brautigan
Brite
Brown
Christiansen Clarke Denham
(11 rows)
booktown=# SELECT isbn FROM editions INTERSECT
SELECT isbn FROM shipments
GROUP BY isbn
HAVING count(id) > 2;
isbn
039480001X
0394800753
0451160916
0590445065
0694003611
(5 rows)
booktown=# SELECT lastname, firstname
FROM authors
EXCEPT
SELECT lastname, firstname
FROM authors AS a (author_id)
NATURAL INNER JOIN books
ORDER BY firstname ASC;
lastname | firstname
Denham | Ariel
Gorey | Edward
Brite | Poppy Z.
Brautigan | Richard
(4 rows)
Команда из листинга 35 возвращает только те записи, которые не входят во второй запрос. Фактически это приводит к тому, что итоговый набор состоит из записей об авторах, у которых нет ни одной книги в таблице books
. Это связано с присутствием секции INNER JOIN
, исключающей из второго запроса всех авторов, коды которых (author_id
) отсутствуют в таблице books
.
Хотя присутствие этих ключевых слов в запросе SQL не позволяет использовать в нем секцию LIMIT
, этот запрет легко обходится благодаря поддержке подзапросов в PostgreSQL. Для этого достаточно заключить в круглые скобки каждый из запросов, участвующих в операции UNION
, INTERSECT
или EXCEPT
, и сравнить итоговые наборы подзапросов, как показано в листинге 36.
booktown=# (SELECT title FROM books ORDER BY title DESC LIMIT 7)
EXCEPT
(SELECT title FROM books ORDER BY title ASC LIMIT 11)
ORDER BY title DESC;
title
The Velveteen Rabbit
The Tell-Tale Heart
The Shining
The Cat in the Hat
(4 rows)
Запрос, использованный в листинге 36, создает по данным таблицы books
набор, отсортированный по названию в алфавитном порядке, и выбирает из него семь последних записей. Затем при помощи ключевого слова EXCEPT
из набора исключаются начальные 11 записей при сортировке в алфавитном порядке по возрастанию. Результат состоит из четырех последних записей таблицы books
, отсортированных в обратном алфавитном порядке завершающей секцией ORDER BY
.
Выбор интервалов записей | Модификация записей командой UPDATE |