Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Объединение двух SELECT-запросов
В SQL существует несколько способов объединить результаты двух SELECT-запросов. Выбор метода зависит от структуры данных, взаимосвязи таблиц и типа объединения.
1. UNION и UNION ALL
UNION объединяет результаты двух запросов, удаляя дубликаты.
SELECT id, name, role FROM employees WHERE department = "Sales"
UNION
SELECT id, name, role FROM managers WHERE status = "active";
UNION ALL объединяет результаты, сохраняя дубликаты (быстрее, чем UNION).
SELECT id, name, amount FROM transactions_2024
UNION ALL
SELECT id, name, amount FROM transactions_2025;
Требования для UNION:
- Одинаковое количество колонок
- Совместимые типы данных
- Имена колонок берутся из первого SELECT
2. JOIN (внутреннее объединение таблиц)
Если две таблицы имеют общий ключ, используй JOIN.
INNER JOIN возвращает только совпадающие строки:
SELECT u.id, u.name, o.order_id, o.amount
FROM users u
INNER JOIN orders o ON u.id = o.user_id
WHERE o.status = "completed";
LEFT JOIN все строки из первой таблицы + совпадающие из второй:
SELECT u.id, u.name, COUNT(o.order_id) as order_count
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
GROUP BY u.id, u.name;
3. Сравнение подходов
Таблица 1: Продажи 2024 Результат: (1, 100), (2, 200)
Таблица 2: Продажи 2025 Результат: (2, 150), (3, 300)
Унион ALL (объединение рядов):
SELECT user_id, amount FROM sales_2024
UNION ALL
SELECT user_id, amount FROM sales_2025;
Результат: (1, 100), (2, 200), (2, 150), (3, 300)
JOIN (объединение по ключу):
SELECT
COALESCE(a.user_id, b.user_id) as user_id,
COALESCE(a.amount, 0) as amount_2024,
COALESCE(b.amount, 0) as amount_2025
FROM sales_2024 a
FULL OUTER JOIN sales_2025 b ON a.user_id = b.user_id;
Результат: (1, 100, 0), (2, 200, 150), (3, 0, 300)
4. WITH (Common Table Expression)
WITH recent_orders AS (
SELECT user_id, order_id, amount
FROM orders
WHERE created_at >= NOW() - INTERVAL "30 days"
),
frequent_users AS (
SELECT user_id, COUNT(*) as order_count
FROM orders
GROUP BY user_id
HAVING COUNT(*) > 5
)
SELECT ro.user_id, COUNT(ro.order_id) as recent
FROM recent_orders ro
LEFT JOIN frequent_users fu ON ro.user_id = fu.user_id
GROUP BY ro.user_id;
5. INTERSECT и EXCEPT
INTERSECT только строки в обоих результатах:
SELECT user_id FROM users_list_a
INTERSECT
SELECT user_id FROM users_list_b;
EXCEPT строки из первого, отсутствующие во втором:
SELECT user_id FROM all_users
EXCEPT
SELECT user_id FROM deleted_users;
6. Производительность
UNION: Медленнее (удаление дубликатов) - используй когда важны уникальные строки UNION ALL: Быстрее (нет дедупликации) - используй когда дубликаты допустимы INNER JOIN: Быстро (индексы на ключах) - используй для связанных данных LEFT JOIN: Среднее - используй когда важны все строки одной таблицы
WITH (CTE): Оптимизируется оптимайзером - лучше для читаемости
7. Оптимизация UNION запросов
Плохо (объединяет результаты, потом фильтрует):
(SELECT * FROM orders_2024
UNION
SELECT * FROM orders_2025)
WHERE status = "completed";
Хорошо (фильтрует перед объединением):
SELECT * FROM orders_2024 WHERE status = "completed"
UNION
SELECT * FROM orders_2025 WHERE status = "completed";
Заключение
Выбор метода объединения запросов зависит от структуры данных: UNION/UNION ALL для вертикального объединения, JOIN для горизонтального объединения по ключу, WITH для читаемости и сложных запросов, INTERSECT/EXCEPT для операций над множествами.