Объединение двух запросов в 1С:Предприятие — одна из самых востребованных операций при работе с данными. Без этого навыка сложно обойтись, когда нужно получить единый отчёт из разных источников, сравнить данные за периоды или скомбинировать результаты из нескольких таблиц. Однако начинающие разработчики часто сталкиваются с ошибками: от синтаксических до логических, когда объединённые данные дублируются или теряются.

В этой статье разберём 5 рабочих методов объединения запросов — от простого UNION до сложных конструкций с временными таблицами. Каждый способ проиллюстрирован реальными примерами кода, которые можно сразу использовать в своих конфигурациях. Особое внимание уделим нюансам производительности: почему некоторые запросы тормозят на больших объёмах данных и как этого избежать.

Если вы работаете с 1С 8.3 или 1С 8.2, все приведённые решения будут актуальны — различия в синтаксисе минимальны. А для тех, кто только осваивает язык запросов, в конце статьи есть FAQ с ответами на типичные ошибки.

1. Метод UNION: простое объединение результатов

Самый очевидный способ объединить два запроса — оператор UNION. Он позволяет "склеить" результаты двух независимых запросов в одну таблицу. Главное правило: структура выборок должна совпадать — одинаковое количество колонок и совместимые типы данных.

Пример: объединим список клиентов из справочника Контрагенты и список поставщиков из документа ПоступлениеТоваров:

ВЫБРАТЬ

Контрагенты.Ссылка КАК Клиент,

Контрагенты.Наименование КАК Имя

ИЗ

Справочник.Контрагенты КАК Контрагенты

ГДЕ

Контрагенты.ЭтоГруппа = ЛОЖЬ

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ

ПоступлениеТоваров.Контрагент КАК Клиент,

ПоступлениеТоваров.Контрагент.Наименование КАК Имя

ИЗ

Документ.ПоступлениеТоваров КАК ПоступлениеТоваров

Обратите внимание на ключевое слово ВСЕ — оно сохраняет все дубликаты. Если нужно убрать повторяющиеся строки, используйте просто ОБЪЕДИНИТЬ (без ВСЕ). Но помните: это может значительно замедлить выполнение на больших объёмах данных.

  • Плюсы: простой синтаксис, работает во всех версиях 1С.
  • ⚠️ Минусы: не подходит для объединения по условию (например, "объединить только те строки, где совпадает дата").
  • 🔹 Когда использовать: когда нужно просто слить два набора данных без дополнительной логики.
💡

Если в объединённых запросах есть колонки с одинаковыми именами, но разными данными (например, Сумма из одного запроса и Сумма из другого), обязательно переименуйте их с помощью КАК, чтобы избежать путаницы.

2. Подзапросы: объединение с условием

Если нужно объединить данные не "в лоб", а по какому-то правилу (например, только те записи, которые есть в обоих запросах), используйте подзапросы. Это гибкий инструмент, который позволяет реализовать логику типа IN, EXISTS или NOT EXISTS.

Пример: найдём товары, которые есть и в справочнике Номенклатура, и в документе РеализацияТоваров за текущий месяц:

ВЫБРАТЬ

Номенклатура.Ссылка КАК Товар,

Номенклатура.Наименование КАК Название

ИЗ

Справочник.Номенклатура КАК Номенклатура

ГДЕ

Номенклатура.Ссылка В (

ВЫБРАТЬ

РеализацияТоваров.Номенклатура

ИЗ

Документ.РеализацияТоваров КАК РеализацияТоваров

ГДЕ

МЕСЯЦ(РеализацияТоваров.Дата) = МЕСЯЦ(ТЕКУЩАЯДАТА())

)

В этом примере внутренний запрос возвращает список товаров из реализаций, а внешний — проверяет, есть ли эти товары в справочнике. Такой подход полезен для фильтрации данных по сложным условиям.

⚠️ Внимание: Подзапросы с EXISTS часто работают быстрее, чем IN, особенно если внутренний запрос возвращает много строк. Пример: ГДЕ СУЩЕСТВУЕТ (ВЫБРАТЬ ...).
Метод Когда использовать Производительность
UNION Простое слияние двух наборов данных ⭐⭐⭐⭐ (быстро, если нет дублей)
Подзапрос с IN Фильтрация по списку значений ⭐⭐ (медленно на больших списках)
Подзапрос с EXISTS Проверка существования связанных данных ⭐⭐⭐⭐⭐ (оптимально для сложных условий)

3. Временные таблицы: для сложных объединений

Когда нужно объединить данные с промежуточной обработкой (например, посчитать агрегаты, отфильтровать, а потом соединить), на помощь приходят временные таблицы. Они позволяют разбить сложный запрос на этапы и избежать громоздких конструкций.

Пример: сначала соберём данные о продажах по регионам, а потом объединим их с данными о остатках на складах:

// Сначала создаём временную таблицу с продажами

ВЫБРАТЬ

Регион.Наименование КАК Регион,

СУММА(Реализация.СуммаДокумента) КАК Продажи

ПОМЕСТИТЬ втПродажи

ИЗ

Документ.РеализацияТоваров КАК Реализация

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Регионы КАК Регион

ПО Реализация.Регион = Регион.Ссылка

СГРУППИРОВАТЬ ПО

Регион.Наименование

ИНДЕКСИРОВАТЬ ПО

Регион

;

// Теперь объединяем с остатками

ВЫБРАТЬ

втПродажи.Регион КАК Регион,

втПродажи.Продажи,

Остатки.ОстатокКоличество КАК Остаток

ИЗ

втПродажи КАК втПродажи

ЛЕВОЕ СОЕДИНЕНИЕ (

ВЫБРАТЬ

РегионыОстатки.Регион КАК Регион,

СУММА(РегистрыНакопления.ОстаткиТоваров.КоличествоОстаток) КАК ОстатокКоличество

ИЗ

РегистрНакопления.ОстаткиТоваров КАК РегистрыНакопления.ОстаткиТоваров

ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Регионы КАК РегионыОстатки

ПО РегистрыНакопления.ОстаткиТоваров.Склад.Регион = РегионыОстатки.Ссылка

СГРУППИРОВАТЬ ПО

РегионыОстатки.Регион

) КАК Остатки

ПО втПродажи.Регион = Остатки.Регион

В этом примере мы сначала сохраняем агрегированные данные о продажах во временную таблицу втПродажи, а потом соединяем её с данными об остатках. Такой подход значительно ускоряет выполнение на больших базах, так как промежуточные результаты не пересчитываются многократно.

  • 📌 Совет: Всегда индексируйте временные таблицы по ключевым полям (как в примере с ИНДЕКСИРОВАТЬ ПО Регион). Это ускорит последующие соединения.
  • 🔄 Альтернатива: Вместо временных таблиц можно использовать ОБЪЕДИНЕНИЕ ЗАПРОСОВ (см. следующий раздел), но они менее гибкие.
📊 Какой метод объединения запросов вы используете чаще?
UNION
Подзапросы
Временные таблицы
Объединение запросов (ОБЪЕДИНЕНИЕ ЗАПРОСОВ)
Не знаю, что это

4. Объединение запросов (ОБЪЕДИНЕНИЕ ЗАПРОСОВ)

В 1С:Предприятие 8.3 появилась специальная конструкция — ОБЪЕДИНЕНИЕ ЗАПРОСОВ. Она позволяет объединить несколько запросов в один результат, при этом каждый запрос может иметь свою структуру (в отличие от UNION, где колонки должны совпадать).

Пример: объединим данные о клиентах и их заказах, где у клиентов и заказов разные поля:

ОБЪЕДИНЕНИЕ ЗАПРОСОВ

ВЫБРАТЬ

"Клиент" КАК Тип,

Контрагенты.Ссылка КАК Ссылка,

Контрагенты.Наименование КАК Наименование,

"" КАК Дата,

"" КАК Сумма

ИЗ

Справочник.Контрагенты КАК Контрагенты

ГДЕ

Контрагенты.ЭтоГруппа = ЛОЖЬ,

ВЫБРАТЬ

"Заказ" КАК Тип,

ЗаказыКлиентов.Клиент КАК Ссылка,

ЗаказыКлиентов.Клиент.Наименование КАК Наименование,

ЗаказыКлиентов.Дата КАК Дата,

ЗаказыКлиентов.СуммаДокумента КАК Сумма

ИЗ

Документ.ЗаказКлиента КАК ЗаказыКлиентов

КОНЕЦ ОБЪЕДИНЕНИЯ

Здесь мы формируем единый результат, где строки с типом "Клиент" содержат данные из справочника, а строки с типом "Заказ" — данные из документов. Это удобно для построения универсальных отчётов, где нужно показать разные сущности в одной таблице.

⚠️ Внимание: Если в объединённых запросах есть колонки с одинаковыми именами, но разными типами данных (например, Дата как дата в одном запросе и как строка в другом), 1С выдаст ошибку. Всегда проверяйте совместимость типов!

5. Соединение таблиц (JOIN): альтернатива объединению

Иногда задачу "объединения" можно решить без UNION или временных таблиц — достаточно правильно использовать соединения таблиц (JOIN). Например, если нужно получить данные из двух таблиц, где есть общий ключ (например, Контрагент), проще сделать СОЕДИНЕНИЕ, чем объединять результаты отдельных запросов.

Пример: получим список клиентов и их заказы за последний месяц:

ВЫБРАТЬ

Контрагенты.Наименование КАК Клиент,

Заказы.Дата КАК ДатаЗаказа,

Заказы.СуммаДокумента КАК Сумма

ИЗ

Справочник.Контрагенты КАК Контрагенты

ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказКлиента КАК Заказы

ПО Контрагенты.Ссылка = Заказы.Клиент

ГДЕ

Заказы.Дата >= НАЧАЛОМЕСЯЦА(ТЕКУЩАЯДАТА())

Здесь мы не объединяем два запроса, а сразу соединяем таблицы по ключу. Это более эффективный способ, если:

  • 🔗 Есть явная связь между таблицами (например, Контрагент → Заказы).
  • 📊 Нужно получить данные в виде "одна строка на связку" (а не "все строки из обоих запросов").
  • ⚡ Требуется максимальная производительность (соединения обычно быстрее, чем UNION + постобработка).
Когда использовать UNION вместо JOIN?

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

- Объединить список активных и архивных клиентов (они хранятся в разных таблицах без прямой связи).

- Слить результаты двух разных отчётов в один.

- Получить все уникальные значения из двух полей (например, все города из справочника клиентов и всех городов из справочника поставщиков).

6. Оптимизация объединённых запросов

Объединение запросов может значительно замедлить работу системы, если не следить за производительностью. Вот ключевые правила оптимизации:

  1. Избегайте UNION без ВСЕ на больших данных.

    Удаление дублей (ОБЪЕДИНИТЬ вместо ОБЪЕДИНИТЬ ВСЕ) требует дополнительных ресурсов. Если дубли не критичны, используйте ВСЕ.

  2. Индексируйте временные таблицы.

    Всегда добавляйте ИНДЕКСИРОВАТЬ ПО для полей, по которым потом будете соединять таблицы.

  3. Разбивайте сложные запросы на части.

    Вместо одного гигантского запроса с 10-ю объединениями лучше использовать временные таблицы или ОБЪЕДИНЕНИЕ ЗАПРОСОВ.

  4. Используйте EXISTS вместо IN.

    Подзапросы с EXISTS обычно работают быстрее, особенно если внутренний запрос возвращает много строк.

Пример оптимизированного запроса с временными таблицами:

// Шаг 1: Получаем уникальных клиентов

ВЫБРАТЬ РАЗЛИЧНЫЕ

Контрагенты.Ссылка КАК Клиент

ПОМЕСТИТЬ втКлиенты

ИЗ

Справочник.Контрагенты КАК Контрагенты

ГДЕ

Контрагенты.ЭтоГруппа = ЛОЖЬ

ИНДЕКСИРОВАТЬ ПО

Клиент

;

// Шаг 2: Получаем их заказы

ВЫБРАТЬ

втКлиенты.Клиент КАК Клиент,

Заказы.Дата КАК ДатаЗаказа,

Заказы.СуммаДокумента КАК Сумма

ИЗ

втКлиенты КАК втКлиенты

ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказКлиента КАК Заказы

ПО втКлиенты.Клиент = Заказы.Клиент

В этом примере мы сначала сокращаем список клиентов до уникальных, а потом соединяем их с заказами. Это в разы быстрее, чем объединение всех клиентов и всех заказов в одном запросе.

💡

Всегда тестируйте производительность объединённых запросов на реальных данных! То, что быстро работает на тестовой базе с 100 записями, может "подвесить" боевую систему с миллионом строк.

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

Можно ли объединить запросы с разным количеством колонок?

Нет, для UNION количество и типы колонок должны совпадать. Если структуры разные, используйте ОБЪЕДИНЕНИЕ ЗАПРОСОВ (доступно в 1С 8.3+) или дополните недостающие колонки пустыми значениями (например, "" КАК ПустоеПоле).

Почему мой запрос с UNION работает очень медленно?

Чаще всего тормоза возникают из-за:

  • Удаления дублей (используйте UNION ALL вместо UNION, если дубли не критичны).
  • Отсутствия индексов на полях соединения.
  • Слишком большого объёма данных (разбейте запрос на части с временными таблицами).

Проверьте план выполнения запроса в Консоли запросов (меню Все функции → План запроса).

Как объединить данные из двух разных баз 1С?

Для объединения данных из разных баз используйте:

  1. Распределённые информационные базы (РИБ). Настройте обмен данными и синхронизацию.
  2. HTTP-сервисы или REST API. Запрашивайте данные из одной базы и загружайте в другую.
  3. Внешние источники данных (для 1С 8.3.14+). Подключите вторую базу как внешний источник и выполняйте запросы к ней напрямую.

Пример подключения внешней базы:

ПодключитьВнешнююБазу("File=C:\Bases\Base2;Usr=Администратор;Pwd=123");
Можно ли в одном запросе использовать UNION и JOIN одновременно?

Да, это допустимо. Например, можно сначала объединить два набора данных с помощью UNION, а потом соединить результат с третьей таблицей:

ВЫБРАТЬ

ОбъединённыеДанные.Поле1,

ТретьяТаблица.Поле2

ИЗ

(

ВЫБРАТЬ Поле1 ИЗ Таблица1

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ Поле1 ИЗ Таблица2

) КАК ОбъединённыеДанные

ЛЕВОЕ СОЕДИНЕНИЕ ТретьяТаблица КАК ТретьяТаблица

ПО ОбъединённыеДанные.Поле1 = ТретьяТаблица.Связь

Как объединить запросы с разными типами данных в колонках?

Если в объединённых запросах есть колонки с одинаковыми именами, но разными типами (например, Число и Строка), 1С выдаст ошибку. Решения:

  • Переименуйте колонки с помощью КАК.
  • Приведите типы к общему (например, СТРОКА(ЧисловоеПоле) КАК ТекстовоеПоле).
  • Используйте ОБЪЕДИНЕНИЕ ЗАПРОСОВ, где колонки могут отличаться.