К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как объединить два запроса в 1С

Как объединить два запроса в 1С через ОБЪЕДИНИТЬ и ОБЪЕДИНИТЬ ВСЕ: синтаксис, отличия, типы полей, типичные ошибки и проверка результата объединения.

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

В языке запросов 1С для этого служит оператор ОБЪЕДИНИТЬ и его разновидность ОБЪЕДИНИТЬ ВСЕ. Они складывают результат двух и более запросов «вертикально»: строки первого запроса дополняются строками второго. Это принципиально отличается от соединения (СОЕДИНЕНИЕ / JOIN), которое сшивает таблицы «горизонтально» по ключу.

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

Чем объединение отличается от соединения

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

Выбирайте объединение, когда нужно сложить однотипные выборки: остатки по двум регистрам, документы «Реализация» и «Возврат», справочники контрагентов-поставщиков и контрагентов-покупателей. Выбирайте соединение, когда нужно обогатить строки дополнительными данными — например, к документу подтянуть реквизиты контрагента.

Объединение или соединение

ОБЪЕДИНИТЬ

Складывает строки двух выборок в одну. Подходит для однотипных данных из разных источников. Число колонок не меняется.

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

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

Временные таблицы + пакетный запрос

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

Синтаксис ОБЪЕДИНИТЬ и ОБЪЕДИНИТЬ ВСЕ

Базовая конструкция выглядит так: первый запрос, ключевое слово ОБЪЕДИНИТЬ, второй запрос. Конструкций может быть больше двух — операторы перечисляются последовательно.

ВЫБРАТЬ

Продажи.Номенклатура КАК Номенклатура,

Продажи.Количество КАК Количество

ИЗ

РегистрНакопления.Продажи КАК Продажи

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

ВЫБРАТЬ

Возвраты.Номенклатура,

-Возвраты.Количество

ИЗ

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

Разница между вариантами одна, но существенная. ОБЪЕДИНИТЬ убирает полностью совпадающие строки — итоговая выборка содержит только уникальные записи. ОБЪЕДИНИТЬ ВСЕ сохраняет все строки из обоих запросов, включая дубликаты.

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

Требования к полям объединяемых запросов

Платформа предъявляет к объединяемым запросам три жёстких требования. Первое — количество полей в каждом запросе должно совпадать. Если в первом запросе три поля, а во втором два, запрос не выполнится.

Второе — типы данных соответствующих колонок должны быть совместимы. Число с числом, строка со строкой, ссылка со ссылкой. Если в первом запросе поле имеет тип «СправочникСсылка.Номенклатура», а во втором — строка, запрос упадёт с ошибкой либо вернёт неожиданный составной тип. Для приведения типов используют функцию ВЫРАЗИТЬ.

Третье — имена итоговых полей берутся из первого запроса. Псевдонимы во втором и последующих запросах игнорируются: соответствие колонок определяется только порядком следования. Поэтому поле «Количество» во втором запросе должно стоять на той же позиции, что и в первом.

ВЫБРАТЬ

ВЫРАЗИТЬ(Таблица1.Контрагент КАК Справочник.Контрагенты) КАК Контрагент,

Таблица1.Сумма КАК Сумма

ИЗ

...

Типичные ошибки
01
Разное количество полей в запросах — запрос не выполняется с ошибкой несоответствия числа полей
02
Несовпадение порядка колонок: сумма попадает в колонку количества, запрос выполняется, но данные искажены
03
Разные типы ссылок (номенклатура и контрагенты в одной колонке) без ВЫРАЗИТЬ — ошибка или непредсказуемый составной тип
04
ОБЪЕДИНИТЬ вместо ОБЪЕДИНИТЬ ВСЕ при расчёте итогов: одинаковые строки пропадают, суммы занижаются
05
Опора на псевдонимы второго запроса — имена полей берутся только из первого запроса

Порядок действий при объединении двух запросов

Начните с того, что напишите и отладьте каждый запрос по отдельности в консоли запросов. Убедитесь, что оба возвращают ожидаемые данные и одинаковый набор колонок по смыслу: номенклатура к номенклатуре, сумма к сумме.

Затем выровняйте типы. Если в одном запросе поле ссылочного типа, а в другом составное или строковое, приведите их через ВЫРАЗИТЬ. Для строк проверьте длину: при объединении строк разной длины итоговый тип может обрезать значения, поэтому длину лучше задать явно, например ВЫРАЗИТЬ(Поле КАК СТРОКА(150)).

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

Порядок действий
  1. 1
    Напишите и проверьте каждый запрос отдельно в консоли запросов
  2. 2
    Приведите колонки к одинаковому количеству, порядку и совместимым типам через ВЫРАЗИТЬ
  3. 3
    Соедините запросы оператором ОБЪЕДИНИТЬ ВСЕ
  4. 4
    Выполните объединённый запрос и сравните число строк с суммой строк исходных запросов
  5. 5
    Добавьте группировку или ИТОГИ, если нужна сводная выборка

Объединение с группировкой и итогами

Частая задача — не просто сложить строки, а свернуть их: получить по каждой номенклатуре суммарное количество с учётом продаж и возвратов. Для этого объединение помещают во вложенный запрос, а снаружи выполняют группировку с агрегатными функциями СУММА, КОЛИЧЕСТВО, МАКСИМУМ.

ВЫБРАТЬ

Данные.Номенклатура КАК Номенклатура,

СУММА(Данные.Количество) КАК Количество

ИЗ

(ВЫБРАТЬ Продажи.Номенклатура КАК Номенклатура,

Продажи.Количество КАК Количество

ИЗ РегистрНакопления.Продажи КАК Продажи

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

ВЫБРАТЬ Возвраты.Номенклатура,

-Возвраты.Количество

ИЗ РегистрНакопления.Возвраты КАК Возвраты) КАК Данные

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

Данные.Номенклатура

Альтернатива — секция ИТОГИ ПО в самом объединённом запросе. Она удобна, когда результат выводится в отчёт с группировками и не нужна промежуточная обработка в коде. Для обхода выборки в модуле вложенный запрос с явной группировкой обычно читается проще.

Учтите ограничение: конструкция УПОРЯДОЧИТЬ ПО применяется ко всему объединению целиком и указывается один раз в конце, а не внутри отдельных запросов. То же относится к секции ИТОГИ.

Когда объединение не подходит: альтернативы

Если запросы существенно разные по структуре, а общих колонок мало, объединение превращается в набор полей, заполненных NULL. В таких случаях лучше собрать промежуточные данные во временные таблицы пакетным запросом и соединить их на финальном шаге либо обработать в коде.

Если объединение используется только чтобы «склеить» периоды или разбить большой запрос на части из соображений производительности, рассмотрите параметризацию: один запрос с условием по периоду и параметром часто решает задачу без ОБЪЕДИНИТЬ.

Наконец, если данные физически однородны (один регистр, разные отборы), почти всегда достаточно одного запроса с составным условием в ГДЕ через ИЛИ — это и проще, и быстрее объединения.

Как проверить результат объединения

Простейшая проверка — арифметическая: число строк результата при ОБЪЕДИНИТЬ ВСЕ должно равняться сумме строк исходных запросов. Выполните каждый запрос отдельно, запомните количество записей, сравните с итогом.

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

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

Контрольные точки

Как проверить результат

Количество строк при ОБЪЕДИНИТЬ ВСЕ
Норма

Равно сумме строк обоих запросов по отдельности

Тревожный признак

Меньше — где-то потеряны строки или случайно использовано ОБЪЕДИНИТЬ

Сумма по числовому полю
Норма

Совпадает с суммой итогов отдельных запросов

Тревожный признак

Расходится — перепутан порядок колонок или знак значения

Типы полей результата
Норма

Ссылки и строки имеют ожидаемые типы и длину

Тревожный признак

Составной тип там, где ожидалась конкретная ссылка, или обрезанные строки

При объединении движений со знаком (продажи минус возвраты) удобно добавить в каждый подзапрос служебное поле-источник, например строку «Продажи» или «Возвраты». Это заметно упрощает отладку: всегда видно, из какого подзапроса пришла конкретная строка.
ПЗ
Практическое замечание

Частые вопросы

Чем ОБЪЕДИНИТЬ отличается от ОБЪЕДИНИТЬ ВСЕ?

ОБЪЕДИНИТЬ удаляет из результата полностью совпадающие строки, ОБЪЕДИНИТЬ ВСЕ сохраняет все строки обоих запросов. Вариант ВСЕ быстрее и предпочтителен, когда дубли невозможны или нужны для суммирования.

Можно ли объединить больше двух запросов?

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

Почему имена полей из второго запроса не видны в результате?

Имена итоговых колонок всегда берутся из первого запроса объединения. Соответствие полей определяется порядком следования, поэтому псевдонимы во втором и последующих запросах игнорируются.

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

Приведите поля к общему типу функцией ВЫРАЗИТЬ, например ВЫРАЗИТЬ(Поле КАК Справочник.Контрагенты) или ВЫРАЗИТЬ(Поле КАК СТРОКА(150)). Для чисел убедитесь, что совпадают длина и точность.

Можно ли отсортировать результат объединения?

Да, но секция УПОРЯДОЧИТЬ ПО указывается один раз в конце всей конструкции и применяется к объединённому результату целиком. Сортировка внутри отдельных запросов объединения не допускается.

Что выбрать: объединение или временные таблицы?

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

Итог

Что важно запомнить

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