Какие операции объединения наборов результатов (SET операторы) существуют в SQL?

Ответ

Операции над множествами (SET операторы) комбинируют результаты двух или более запросов SELECT. Все запросы должны иметь одинаковое количество столбцов с совместимыми типами данных.

Основные операторы:

  1. UNION — объединяет результаты, удаляя дубликаты.

    -- Найти всех уникальных пользователей из двух таблиц
    SELECT user_email FROM website_users
    UNION
    SELECT user_email FROM mobile_users;
  2. UNION ALL — объединяет результаты, сохраняя все строки, включая дубликаты. Работает быстрее UNION, так как не требует сортировки и дедупликации.

    -- Объединить все заказы, включая повторяющиеся (если такие возможны)
    SELECT order_id FROM orders_2023
    UNION ALL
    SELECT order_id FROM orders_2024;
  3. INTERSECT — возвращает только общие строки, присутствующие в результатах обоих запросов. (Поддержка зависит от СУБД).

    -- Найти товары, которые покупали и в январе, и в феврале
    SELECT product_id FROM january_sales
    INTERSECT
    SELECT product_id FROM february_sales;
  4. EXCEPT (или MINUS в Oracle) — возвращает строки из первого запроса, которых нет во втором.

    -- Найти пользователей, которые есть в старой базе, но не мигрировали в новую
    SELECT customer_id FROM legacy_database
    EXCEPT
    SELECT customer_id FROM new_system;

Важные особенности:

  • Порядок и имена столбцов в результирующем наборе определяются первым запросом.
  • Для UNION, INTERSECT, EXCEPT СУБД неявно выполняет сортировку для удаления дубликатов, что может быть ресурсоемко на больших данных.
  • UNION ALL — предпочтительный выбор для объединения непересекающихся или уже уникальных данных из-за производительности.

Ответ 18+ 🔞

Ну, слушай, смотри, как оно бывает. Сидишь ты такой, пишешь запросы, а потом бац — надо два результата склеить в один. Вот для этого и есть SET-операторы, этакие склейщики для SELECT'ов. Но есть, блядь, железное правило: оба запроса должны выплевывать одинаковое количество колонок, и типы данных там должны быть, ну, чтоб друг другу не противоречить, а то получится пиздец, а не результат.

Вот основные приблуды:

  1. UNION — склеивает всё в кучу, но как приличный человек — убирает повторы. Чисто, аккуратно, но небыстро.

    -- Найти всех уникальных пользователей из двух таблиц
    SELECT user_email FROM website_users
    UNION
    SELECT user_email FROM mobile_users;

    Получишь список почт, и каждая только по разу, даже если Петя сидит и с сайта, и с телефона.

  2. UNION ALL — а это уже по-хамски. Берёт и лепит всё подряд, хоть десять одинаковых строк. Зато, ёпта, быстрее, потому что не тратит время на "ой, это уже было" — просто пашет.

    -- Объединить все заказы, включая повторяющиеся (если такие возможны)
    SELECT order_id FROM orders_2023
    UNION ALL
    SELECT order_id FROM orders_2024;

    Идеально, когда точно знаешь, что дублей нет или они тебе похуй.

  3. INTERSECT — оператор для мажоров, ищет общее. Вернёт только то, что есть и там, и там. Но поддерживается не везде, хитрая жопа.

    -- Найти товары, которые покупали и в январе, и в феврале
    SELECT product_id FROM january_sales
    INTERSECT
    SELECT product_id FROM february_sales;

    Только самые популярные позиции, которые народ таскает и зимой, и почти зимой.

  4. EXCEPT (или MINUS в Oracle) — а это уже по-нашему, по-русски: "Мне отдай то, чего у него нет". Берёт результат первого запроса и выкидывает из него всё, что есть во втором.

    -- Найти пользователей, которые есть в старой базе, но не мигрировали в новую
    SELECT customer_id FROM legacy_database
    EXCEPT
    SELECT customer_id FROM new_system;

    Вот они, распиздяи, которые застряли в прошлом веке. Надо их пинать.

А теперь, блядь, важные детали, чтоб не обосраться:

  • Как назвать колонки в итоге и в каком порядке они будут — решает первый запрос. Остальные — просто подтягиваются.
  • UNION, INTERSECT, EXCEPT — они все любят порядок. Чтобы убрать дубли, система негласно всё сортирует. На маленьких данных — похуй, а на овердохуища — это может быть пиздец как долго.
  • Поэтому запомни: если уверен, что дублей не будет или они не страшны — всегда юзай UNION ALL. Быстрее, проще, и сервер тебе спасибо скажет. Ну, в смысле, не скажет, но хотя бы не ляжет.