Операции над множествами: UNION, INTERSECT, EXCEPT

UNION, INTERSECT и EXCEPT комбинируют результаты двух запросов как множества.

UNION — объединение (строки из обоих, дубликаты убраны). INTERSECT — пересечение (строки, что есть в обоих). EXCEPT — разность (строки первого, которых нет во втором).

Условие применимости

Множественные операции склеивают результаты двух SELECT по вертикали. Требование: одинаковое число колонок и совместимые типы. Сопоставление идёт по позиции, а не по имени.

UNION: объединение без дубликатов

CREATE TABLE online(name TEXT);
INSERT INTO online VALUES ('Аня'),('Борис'),('Вика');
CREATE TABLE offline(name TEXT);
INSERT INTO offline VALUES ('Борис'),('Вика'),('Глеб');

SELECT name FROM online
UNION
SELECT name FROM offline
ORDER BY name;

Вывод:

name
-----
Аня
Борис
Вика
Глеб

Борис и Вика есть в обеих таблицах, но в результате по одному разу — UNION убирает дубликаты.

UNION vs UNION ALL

UNION отсеивает повторы — а для этого ему приходится сортировать/хешировать данные, что стоит ресурсов. UNION ALL просто склеивает результаты, не убирая дубли, и потому заметно быстрее. Если вы знаете, что пересечений нет (или дубли вам нужны), всегда берите UNION ALL.

SELECT 1 AS x
UNION ALL
SELECT 1
UNION ALL
SELECT 2;

Вывод:

x
-
1
1
2

INTERSECT: пересечение

CREATE TABLE online(name TEXT);
INSERT INTO online VALUES ('Аня'),('Борис'),('Вика');
CREATE TABLE offline(name TEXT);
INSERT INTO offline VALUES ('Борис'),('Вика'),('Глеб');

SELECT name FROM online
INTERSECT
SELECT name FROM offline;

Вывод:

name
-----
Борис
Вика

Остались только те, кто есть и онлайн, и офлайн.

EXCEPT: разность

CREATE TABLE online(name TEXT);
INSERT INTO online VALUES ('Аня'),('Борис'),('Вика');
CREATE TABLE offline(name TEXT);
INSERT INTO offline VALUES ('Борис'),('Вика'),('Глеб');

SELECT name FROM online
EXCEPT
SELECT name FROM offline;

Вывод:

name
----
Аня

Аня есть онлайн, но нет офлайн. EXCEPT отвечает на вопрос «что есть только в первом наборе» — например, «какие товары были на складе вчера, но не сегодня».

Памятка

ОперацияРезультат
UNIONстроки из обоих, дубли убраны
UNION ALLстроки из обоих, дубли сохранены (быстрее)
INTERSECTстроки, присутствующие в обоих
EXCEPTстроки первого, которых нет во втором

Итог

  • Множественные операции требуют одинакового числа колонок и совпадения типов по позиции.
  • UNION убирает дубли (дороже), UNION ALL их сохраняет (быстрее) — по умолчанию предпочитайте ALL, если дубли не страшны.
  • INTERSECT — общее, EXCEPT — «есть в первом, нет во втором».
Проверьте себя
1. Чем UNION отличается от UNION ALL?
AUNION сохраняет дубли, UNION ALL убирает
BUNION убирает дубликаты (и потому медленнее), UNION ALL сохраняет все строки (быстрее)
CОни идентичны
DUNION ALL сортирует результат
2. Что вернёт EXCEPT для online={Аня,Борис,Вика} и offline={Борис,Вика,Глеб} в порядке online EXCEPT offline?
AБорис, Вика
BАня
CГлеб
DАня, Глеб
3. Какое требование обязательно для UNION/INTERSECT/EXCEPT?
AТаблицы должны иметь одинаковые имена
BОба SELECT должны возвращать одинаковое число колонок с совместимыми типами (сопоставление по позиции)
CОбязателен JOIN
DНужен общий первичный ключ
Поддержать проект