UNION и JOIN в PostgreSQL: что нужно знать до начала
UNION складывает строки из нескольких запросов, JOIN соединяет связанные строки из таблиц. На простом примере разберём разницу, проверим результат в PostgreSQL и покажем ошибки, из-за которых запрос не выполняется или возвращает не те данные.

За 15–20 минут вы сможете запустить два запроса в PostgreSQL и понять, когда нужен UNION, а когда JOIN. Главное различие простое: UNION добавляет строки одного набора к строкам другого, а JOIN собирает связанные данные в общие строки.
Что нужно до начала
Пример рассчитан на PostgreSQL 16 и новее: здесь используется базовый синтаксис, который есть и в более ранних версиях. Нужен доступ к базе и любой SQL-клиент: например, psql или графический клиент. Создавать таблицы можно в тестовой базе, где у вас есть право выполнять SQL.
Запросы ниже создают таблицы с именами north_orders и south_orders. Если такие таблицы уже есть, выберите другие имена или используйте отдельную тестовую схему. Не запускайте примеры в рабочей базе, если не уверены, что сможете удалить созданные таблицы.
Сначала соберите строки через UNION
Представьте, что заказы двух магазинов хранятся отдельно, но имеют одинаковую структуру. Чтобы получить общий список, результаты двух запросов нужно поставить друг под другом. Для этого используют UNION.
Создайте таблицы и добавьте по две записи. Проверка: каждый оператор должен завершиться без сообщения об ошибке.
CREATE TABLE north_orders ( order_id integer, customer_name text, amount numeric(10, 2) ); CREATE TABLE south_orders ( order_id integer, customer_name text, amount numeric(10, 2) ); INSERT INTO north_orders (order_id, customer_name, amount) VALUES (1, 'Анна', 1200.00), (2, 'Илья', 850.00); INSERT INTO south_orders (order_id, customer_name, amount) VALUES (3, 'Ольга', 2100.00), (4, 'Марк', 450.00);Запустите объединение. Проверка: результат содержит четыре строки и три столбца.
SELECT order_id, customer_name, amount FROM north_orders UNION SELECT order_id, customer_name, amount FROM south_orders;Замените
UNIONнаUNION ALL. Проверка: для этих данных вы снова получите четыре строки. Разница станет заметна, когда совпадут все значения выбранных столбцов.
UNION убирает повторяющиеся строки результата, а UNION ALL сохраняет их. Если повторы важны — например, каждая запись означает отдельный заказ, — обычно нужен именно UNION ALL. Устранение дублей требует дополнительной обработки результата; не выбирайте UNION просто «на всякий случай».
UNION отвечает на вопрос «как сложить похожие списки?», JOIN — «как добавить к строке связанные сведения?»
Как соединить связанные данные через JOIN
Теперь добавим отдельный справочник клиентов. Заказы содержат идентификатор клиента, а справочник — его имя. Здесь надо не складывать два набора заказов, а найти соответствие между каждой записью заказа и клиентом.
Создайте таблицу клиентов и измените структуру заказов, добавив идентификатор клиента. Проверка: команда
ALTER TABLEвыполняется для обеих таблиц.CREATE TABLE customers ( customer_id integer, customer_name text ); ALTER TABLE north_orders ADD COLUMN customer_id integer; ALTER TABLE south_orders ADD COLUMN customer_id integer; INSERT INTO customers (customer_id, customer_name) VALUES (10, 'Анна'), (20, 'Илья'), (30, 'Ольга'), (40, 'Марк'); UPDATE north_orders SET customer_id = 10 WHERE order_id = 1; UPDATE north_orders SET customer_id = 20 WHERE order_id = 2; UPDATE south_orders SET customer_id = 30 WHERE order_id = 3; UPDATE south_orders SET customer_id = 40 WHERE order_id = 4;Выполните соединение заказов одного магазина со справочником. Проверка: в результате будут четыре поля, включая сумму и имя клиента.
SELECT orders.order_id, customers.customer_name, orders.amount FROM north_orders AS orders JOIN customers ON customers.customer_id = orders.customer_id;Подставьте вместо
north_ordersтаблицуsouth_orders. Проверка: запрос покажет заказы второго магазина и соответствующие имена.
JOIN сопоставляет строки по условию после ON. В примере ключом связи служит customer_id. Если соответствие нужно сохранить даже для заказа без найденного клиента, рассмотрите LEFT JOIN: он оставляет все строки левой таблицы, а недостающие значения правой стороны показывает как NULL.
Как не перепутать операции
Посмотрите на форму результата, которую вы хотите получить. Если нужны записи из нескольких одинаково устроенных источников в одном списке, выбирайте UNION. Если к каждой записи нужно присоединить поля из другой таблицы, выбирайте JOIN.
- UNION: число столбцов в обеих частях должно совпадать, а типы соответствующих столбцов должны быть совместимы. Названия столбцов задаёт первый запрос.
- JOIN: укажите условие связи в
ON. Если подходящих строк справа несколько, одна строка слева появится в результате несколько раз. - Порядок результата: ни UNION, ни JOIN сами по себе не обещают нужный порядок строк. Если важна сортировка, добавьте
ORDER BYв конец всего запроса.
Дубликат1 — строка результата, совпадающая с другой по выбранным столбцам. Для UNION важно именно совпадение результата целиком, а не только одинаковый идентификатор в одной колонке.
Если запрос не сработал
- «each UNION query must have the same number of columns» — в частях UNION разное число выбранных столбцов. Сверьте списки после SELECT и оставьте одинаковое количество.
- «UNION types ... cannot be matched» — PostgreSQL не может согласовать типы соответствующих столбцов, например число и текст. Сопоставьте типы или явно преобразуйте значение через
CAST(... AS ...). - «relation ... does not exist» — таблица не найдена в текущей схеме либо в имени есть опечатка. Проверьте имя и схему; если таблица создана в другой схеме, укажите её перед именем.
- JOIN возвращает больше строк, чем ожидалось. Проверьте, уникален ли ключ в присоединяемой таблице: несколько совпадений для одного ключа размножают строки результата.
- JOIN не показывает часть заказов. При обычном
JOINбез совпадения строки отбрасываются. Если их нужно сохранить, проверьте, подходит лиLEFT JOIN, и выясните, почему не совпало условие связи.
Что проверить дальше
После примеров проверьте запрос на реальных данных: сравните число строк до и после UNION, посмотрите на повторы, а для JOIN проверьте уникальность ключа в справочнике. Если набор большой, изучите план запроса через EXPLAIN и измерьте время на тех же данных, с которыми работает приложение. Вопросы о фильтрации, индексах и оптимизации зависят от структуры таблиц и объёма данных; здесь мы разбирали только смысл UNION и JOIN.
1 В SQL под дублями здесь имеется в виду совпадение всех значений столбцов, выбранных в результате UNION.
Проверка рекламы на риски: Что в макете вызовет вопросы ФАС: превосходные степени, сравнения, обещания результата, маркировка.
Спросить за 40 ₽Источники: PostgreSQL 16: Combining Queries (UNION, INTERSECT, EXCEPT), PostgreSQL 16: Table Expressions — Joins
Частые вопросы
UNION и UNION ALL — в чём разница?
Можно ли использовать UNION для таблиц с разными столбцами?
Почему JOIN возвращает дубли?
Что выбрать, если записи нужно сохранить даже без совпадения?
Примеры подойдут для другой версии PostgreSQL?
Что делать, если таблица существует, но запрос пишет, что её нет?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.