UNION и JOIN в PostgreSQL: короткое руководство
UNION складывает строки из нескольких запросов, JOIN связывает столбцы по условию. Разберём разницу на примерах для PostgreSQL 16, покажем, когда дубликаты исчезают и как проверить результат.

Что понадобится
За несколько минут вы научитесь выбирать между UNION и JOIN в PostgreSQL 16 и проверите результат на небольших запросах. Нужны только доступ к базе и любой SQL-клиент, например psql. Примеры не создают таблицы и не меняют данные: их можно выполнять по одному прямо в редакторе запросов.
Короткое правило: UNION объединяет строки с одинаковой структурой, а JOIN добавляет к строкам столбцы из связанной таблицы. Если перепутать операции, запрос может вернуть не те данные или неожиданно размножить строки.
Шаг 1. Сложите результаты через UNION
Представьте, что сотрудники двух отделов записаны в разных списках. У каждого списка одинаковые поля: имя и должность. В PostgreSQL такой результат удобно собрать через UNION:
SELECT 'Анна' AS name, 'аналитик' AS role
UNION
SELECT 'Илья' AS name, 'разработчик' AS role;Запрос должен вернуть две строки и два столбца: name и role. UNION соединяет результаты по вертикали: столбцы второго запроса попадают в те же позиции, что и столбцы первого.
Проверьте структуру обоих частей: в них должно быть одинаковое количество столбцов, а типы значений в соответствующих позициях должны быть совместимы. Имена столбцов итогового результата задаёт первый SELECT.
Шаг 2. Решите, нужны ли повторы
Обычный UNION удаляет дубликаты из общего результата. Если повторяющиеся строки важны, используйте UNION ALL:
SELECT 'Анна' AS name
UNION
SELECT 'Анна' AS name;
SELECT 'Анна' AS name
UNION ALL
SELECT 'Анна' AS name;В первом результате будет одна строка, во втором — две. Проверка простая: запустите запросы отдельно и сравните число строк. Удаление дубликатов требует дополнительной обработки результата, поэтому не выбирайте обычный UNION автоматически, если уникальность вам не нужна.
Дубликатом считается совпадающая строка результата, а не обязательно запись с одинаковым первичным ключом в исходных таблицах. Если в запрос включить разные значения, например источник записи, строки уже могут отличаться.
Шаг 3. Соедините связанные данные через JOIN
Теперь возьмём другой случай: есть список покупателей и список заказов. Нужно показать имя покупателя рядом с номером его заказа. Здесь запрос должен сопоставить строки по идентификатору, то есть добавить столбцы через JOIN:
WITH customers (id, name) AS (
VALUES
(1, 'Анна'),
(2, 'Илья')
),
orders (id, customer_id, order_no) AS (
VALUES
(10, 1, 'A-100'),
(11, 1, 'A-101'),
(12, 2, 'B-200')
)
SELECT customers.name, orders.order_no
FROM customers
JOIN orders ON orders.customer_id = customers.id
ORDER BY orders.order_no;Должны появиться три строки: у Анны два заказа, у Ильи один. Условие после ON объясняет PostgreSQL, какие записи связаны. Если убрать это условие, запрос может соединить каждую строку с каждой; результат резко разрастётся.
Шаг 4. Сверьте выбор операции
- Используйте
UNION, когда нужно сложить однотипные результаты в общий список: например, записи из двух источников с одинаковыми полями. - Используйте
JOIN, когда нужно собрать сведения об одной сущности из связанных таблиц: например, имя покупателя и его заказы. - Используйте
UNION ALL, если строки из разных запросов нужно сохранить, включая повторы.
Проверка перед запуском: спросите себя, должен ли результат стать длиннее за счёт новых строк или шире за счёт новых столбцов. Первый случай обычно ведёт к UNION, второй — к JOIN.
Если вы складываете однотипные списки — смотрите на UNION. Если дополняете запись данными из связанной таблицы — смотрите на JOIN. Ошибка обычно начинается с неверного представления о форме результата.
Если запрос не сработал
- «each UNION query must have the same number of columns». В частях
UNIONразное число столбцов. Добавьте недостающее значение или уберите лишний столбец, сохранив одинаковую структуру. - Ошибка о несовместимых типах. В одной позиции, например, выбраны число и текст. Приведите значения к совместимым типам; PostgreSQL указывает причину и позиции в сообщении об ошибке.
- После JOIN строк намного больше, чем ожидалось. Проверьте условие
ONи уникальность ключа на стороне, где вы ожидали одну запись. Если совпадений несколько, одна строка другой таблицы появится в результате несколько раз. - Строки пропали после JOIN. Обычный
JOINвозвращает только пары, для которых нашлось совпадение. Если нужно сохранить все строки слева, изучитеLEFT JOIN; детали внешних соединений здесь не разбираем. - Результат идёт не в нужном порядке. Без
ORDER BYпорядок строк не гарантирован. Добавьте сортировку в конце запроса; при использованииUNIONсортируется общий результат.
Термин: кардинальность
Кардинальность соединения — число строк, которое получается при сопоставлении записей двух наборов. Если одному покупателю соответствуют три заказа, соединение вернёт три строки для этого покупателя. Поэтому перед JOIN полезно проверить, уникален ли ключ на стороне, которую вы считаете «одной записью».
Что делать дальше
Возьмите запрос, который собираетесь написать, и сначала опишите ожидаемую форму результата: сколько в нём столбцов и откуда берутся строки. Для JOIN отдельно проверьте ключи и количество совпадений; для UNION — число и типы столбцов, а также необходимость сохранять дубликаты. На реальных данных сравните ожидаемое количество строк с фактическим.
Примеры рассчитаны на PostgreSQL 16; базовые формы UNION и JOIN применяются и в других версиях, но для конкретной версии сверяйте синтаксис и поведение с официальной документацией.
Субтитры и таймкоды: Расшифровка речи и субтитры по правилам читаемости: 42 знака в строке, две строки, минимум секунда на реплику.
Спросить за 40 ₽Источники: PostgreSQL 16: объединение запросов (UNION), PostgreSQL 16: объединение таблиц (JOIN)
Частые вопросы
Можно ли объединить через UNION таблицы с разными столбцами?
Почему UNION удалил строки?
JOIN всегда возвращает по одной строке на запись?
Чем JOIN отличается от UNION простыми словами?
Работают ли эти примеры в другой версии PostgreSQL?
Как сохранить строки, для которых не нашлось пары в JOIN?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.