Ответ
Операции над множествами (SET операторы) комбинируют результаты двух или более запросов SELECT. Все запросы должны иметь одинаковое количество столбцов с совместимыми типами данных.
Основные операторы:
-
UNION— объединяет результаты, удаляя дубликаты.-- Найти всех уникальных пользователей из двух таблиц SELECT user_email FROM website_users UNION SELECT user_email FROM mobile_users; -
UNION ALL— объединяет результаты, сохраняя все строки, включая дубликаты. Работает быстрееUNION, так как не требует сортировки и дедупликации.-- Объединить все заказы, включая повторяющиеся (если такие возможны) SELECT order_id FROM orders_2023 UNION ALL SELECT order_id FROM orders_2024; -
INTERSECT— возвращает только общие строки, присутствующие в результатах обоих запросов. (Поддержка зависит от СУБД).-- Найти товары, которые покупали и в январе, и в феврале SELECT product_id FROM january_sales INTERSECT SELECT product_id FROM february_sales; -
EXCEPT(илиMINUSв Oracle) — возвращает строки из первого запроса, которых нет во втором.-- Найти пользователей, которые есть в старой базе, но не мигрировали в новую SELECT customer_id FROM legacy_database EXCEPT SELECT customer_id FROM new_system;
Важные особенности:
- Порядок и имена столбцов в результирующем наборе определяются первым запросом.
- Для
UNION,INTERSECT,EXCEPTСУБД неявно выполняет сортировку для удаления дубликатов, что может быть ресурсоемко на больших данных. UNION ALL— предпочтительный выбор для объединения непересекающихся или уже уникальных данных из-за производительности.
Ответ 18+ 🔞
Ну, слушай, смотри, как оно бывает. Сидишь ты такой, пишешь запросы, а потом бац — надо два результата склеить в один. Вот для этого и есть SET-операторы, этакие склейщики для SELECT'ов. Но есть, блядь, железное правило: оба запроса должны выплевывать одинаковое количество колонок, и типы данных там должны быть, ну, чтоб друг другу не противоречить, а то получится пиздец, а не результат.
Вот основные приблуды:
-
UNION— склеивает всё в кучу, но как приличный человек — убирает повторы. Чисто, аккуратно, но небыстро.-- Найти всех уникальных пользователей из двух таблиц SELECT user_email FROM website_users UNION SELECT user_email FROM mobile_users;Получишь список почт, и каждая только по разу, даже если Петя сидит и с сайта, и с телефона.
-
UNION ALL— а это уже по-хамски. Берёт и лепит всё подряд, хоть десять одинаковых строк. Зато, ёпта, быстрее, потому что не тратит время на "ой, это уже было" — просто пашет.-- Объединить все заказы, включая повторяющиеся (если такие возможны) SELECT order_id FROM orders_2023 UNION ALL SELECT order_id FROM orders_2024;Идеально, когда точно знаешь, что дублей нет или они тебе похуй.
-
INTERSECT— оператор для мажоров, ищет общее. Вернёт только то, что есть и там, и там. Но поддерживается не везде, хитрая жопа.-- Найти товары, которые покупали и в январе, и в феврале SELECT product_id FROM january_sales INTERSECT SELECT product_id FROM february_sales;Только самые популярные позиции, которые народ таскает и зимой, и почти зимой.
-
EXCEPT(илиMINUSв Oracle) — а это уже по-нашему, по-русски: "Мне отдай то, чего у него нет". Берёт результат первого запроса и выкидывает из него всё, что есть во втором.-- Найти пользователей, которые есть в старой базе, но не мигрировали в новую SELECT customer_id FROM legacy_database EXCEPT SELECT customer_id FROM new_system;Вот они, распиздяи, которые застряли в прошлом веке. Надо их пинать.
А теперь, блядь, важные детали, чтоб не обосраться:
- Как назвать колонки в итоге и в каком порядке они будут — решает первый запрос. Остальные — просто подтягиваются.
UNION,INTERSECT,EXCEPT— они все любят порядок. Чтобы убрать дубли, система негласно всё сортирует. На маленьких данных — похуй, а на овердохуища — это может быть пиздец как долго.- Поэтому запомни: если уверен, что дублей не будет или они не страшны — всегда юзай
UNION ALL. Быстрее, проще, и сервер тебе спасибо скажет. Ну, в смысле, не скажет, но хотя бы не ляжет.