Разработка и Конфигурация · 11 мин
Как объединить два запроса в 1С
Как объединить два запроса в 1С через ОБЪЕДИНИТЬ и ОБЪЕДИНИТЬ ВСЕ: синтаксис, отличия, типичные ошибки, примеры кода и проверка результата объединения.
Объединение двух запросов в языке запросов 1С выполняется операторами ОБЪЕДИНИТЬ и ОБЪЕДИНИТЬ ВСЕ. Оба складывают строки двух выборок в один результат, но по-разному обрабатывают дубликаты: первый убирает повторяющиеся строки, второй сохраняет все. Выбор оператора влияет и на корректность данных, и на скорость выполнения.
Типовая задача — собрать в одну таблицу данные из разных источников: например, остатки по двум складам, движения по регистрам накопления и сведений или список контрагентов из справочника и из документов. Во всех этих случаях объединение заменяет обход нескольких результатов в коде и упрощает дальнейшую обработку: группировку, сортировку, вывод в отчёт на СКД.
Главное требование к объединяемым запросам — одинаковый состав и порядок полей. Количество колонок в каждой части должно совпадать, а типы соответствующих полей должны быть совместимы. Имена полей итоговой выборки берутся из первого запроса, поэтому во второй части часто применяют псевдонимы и приведение типов через ВЫРАЗИТЬ.
Чем ОБЪЕДИНИТЬ отличается от ОБЪЕДИНИТЬ ВСЕ
Оператор ОБЪЕДИНИТЬ формирует результат без повторяющихся строк: если обе выборки содержат одинаковую строку, в итог попадает только одна копия. Это удобно, когда нужен список уникальных значений — например, перечень номенклатуры, которая встречается хотя бы в одном из двух документов.
Оператор ОБЪЕДИНИТЬ ВСЕ просто складывает строки обеих выборок, не проверяя совпадения. Если одна и та же запись есть в обеих частях, она появится в результате дважды. За счёт отсутствия проверки дублей этот вариант работает заметно быстрее на больших объёмах данных.
Практическое правило: если дубли заведомо невозможны (источники не пересекаются, например движения разных регистров) или дубли нужны для суммирования — используйте ОБЪЕДИНИТЬ ВСЕ. Если пересечения возможны и недопустимы — применяйте ОБЪЕДИНИТЬ либо группируйте результат после ОБЪЕДИНИТЬ ВСЕ.
Сравнение вариантов
Убирает одинаковые строки. Подходит для уникальных списков, но медленнее на больших выборках.
Сохраняет все строки обеих частей. Быстрее, оптимально для последующей группировки и суммирования.
Синтаксис объединения двух запросов
Конструкция состоит из двух полноценных секций ВЫБРАТЬ, разделённых оператором объединения. Сортировка ИТОГИ и УПОРЯДОЧИТЬ ПО указываются один раз — в конце всего запроса, а не в каждой части.
ВЫБРАТЬ
Продажи.Номенклатура КАК Номенклатура,
Продажи.СуммаОборот КАК Сумма
ИЗ
РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК Продажи
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
Возвраты.Номенклатура,
-Возвраты.СуммаОборот
ИЗ
РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК Возвраты
Обратите внимание: во второй части псевдонимы полей можно не указывать — имена колонок результата определяются первым запросом. Однако порядок полей строго позиционный: первая колонка первой части объединяется с первой колонкой второй части, вторая — со второй и так далее.
Если частей больше двух, операторы перечисляются подряд: ВЫБРАТЬ ... ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ... ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ ... — ограничений на число объединяемых частей для практических задач обычно не возникает.
- 1Сформулируйте первый запрос и определите состав полей результата
- 2Напишите второй запрос с тем же количеством полей в том же порядке
- 3Выровняйте типы полей через ВЫРАЗИТЬ или подбор совместимых источников
- 4Выберите оператор: ОБЪЕДИНИТЬ для уникальных строк, ОБЪЕДИНИТЬ ВСЕ для суммирования
- 5Проверьте результат в консоли запросов: количество строк и итоговые суммы
Требования к полям объединяемых запросов
Платформа проверяет объединение по трём критериям: количество полей, порядок их следования и совместимость типов. Нарушение любого из них приводит к ошибке при выполнении запроса или при проверке модуля.
Совместимость типов не означает полного совпадения. Числовые поля с разной разрядностью обычно объединяются без проблем, но строка и число в одной позиции вызовут ошибку. Составные типы (например, ссылка на разные справочники) допустимы, однако могут замедлить выполнение и усложнить последующие соединения.
Когда типы различаются, применяйте функцию ВЫРАЗИТЬ для явного приведения:
ВЫБРАТЬ
ВЫРАЗИТЬ(Данные.Количество КАК ЧИСЛО(15, 3)) КАК Количество
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки КАК Данные
Также полезно добавлять служебное поле-метку источника — строковую константу, которая показывает, из какой части пришла строка. Это упрощает отладку и позволяет фильтровать результат без повторного запроса.
Практические сценарии объединения
Остатки по нескольким складам или организациям
Когда данные физически хранятся в одном регистре, объединение не нужно — достаточно отбора. Но если учёт разнесён по разным регистрам (например, «ТоварыНаСкладах» и «ТоварыПереданныеНаКомиссию»), объединение двух выборок даёт сводную картину. Здесь корректен ОБЪЕДИНИТЬ ВСЕ с последующей группировкой по номенклатуре и суммированием количества.
Сводная таблица документов разных видов
Частая задача — вывести в один список поступления и реализации с общими колонками «Дата», «Контрагент», «Сумма». У документов разные таблицы, поэтому каждая часть выбирает свой источник, а поле «ВидДокумента» заполняется строковой константой. Результат упорядочивается по дате уже после объединения.
Данные регистра и справочника
Объединение применяют, чтобы показать элементы справочника, у которых есть и нет движений, в одной выборке с разными признаками. Однако если цель — просто «не потерять» элементы без движений, часто правильнее использовать левое соединение: оно читается проще и не плодит лишние строки.
Как выбрать действие
Объединение в консоли запросов и в СКД
Перед встраиванием в код отлаживайте объединение в консоли запросов: она сразу показывает ошибки несовпадения полей и позволяет сравнить количество строк каждой части с итоговым результатом. В типовых конфигурациях есть встроенная консоль, для файловых баз подходят внешние обработки-консоли.
В схеме компоновки данных объединение работает так же — текст запроса набора данных поддерживает ОБЪЕДИНИТЬ и ОБЪЕДИНИТЬ ВСЕ. Дополнительно СКД позволяет объединять наборы данных на уровне самой схемы (тип связи «Объединение»), что удобно, когда источники формируются разными запросами с собственными параметрами.
При переносе отлаженного текста в модуль не забывайте передавать параметры: периоды, отборы по организации, ссылки. Параметр объявляется один раз, даже если используется в обеих частях объединения, — платформа подставит его везде.
Если после объединения результат группируется и суммируется, почти всегда выгоднее ОБЪЕДИНИТЬ ВСЕ: группировка сама устранит визуальные дубли, а платформа не потратит время на их поиск до агрегации.
Типичные ошибки и как их избежать
Самая частая ошибка — разное количество полей в частях объединения. Платформа сообщит об этом явно, но место несоответствия приходится искать вручную. Профилактика проста: сначала выпишите список колонок результата, затем подгоняйте под него каждую часть, добавляя NULL или константы для отсутствующих данных.
Вторая группа проблем — несовпадение типов: ссылка на справочник в одной части и строка в другой, разная длина строк, число и дата. Решается через ВЫРАЗИТЬ или заменой поля на совместимое. Третья ошибка — ожидание, что ОБЪЕДИНИТЬ «склеит» строки по ключу, как соединение: объединение не сопоставляет строки друг с другом, а просто складывает их в одну кучу.
Отдельно стоит сортировка: конструкция УПОРЯДОЧИТЬ ПО внутри одной из частей объединения запрещена. Если нужен определённый порядок — укажите его после последней части. То же относится к итогам: ИТОГИ ПО пишется один раз для всего объединённого запроса.
Проверка результата объединения
После написания запроса убедитесь, что объединение отработало корректно. Базовая проверка — арифметическая: при ОБЪЕДИНИТЬ ВСЕ число строк результата должно равняться сумме строк обеих частей. Если оно меньше — вероятно, где-то использован ОБЪЕДИНИТЬ или сработал отбор.
Для денежных и количественных показателей сверьте контрольные суммы: итог по полю «Сумма» в объединённом запросе должен совпадать с суммой итогов отдельных выборок. Расхождение — признак потери строк, неверного знака (например, забытый минус у возвратов) или лишнего отбора.
Как проверить результат
Равно сумме строк обеих частей
Меньше суммы — строки теряются, проверьте оператор и отборы
Совпадает с суммой итогов отдельных запросов
Расходится — проверьте знаки, отборы и дубли
Однородные значения в каждой колонке
Смешение типов — добавьте ВЫРАЗИТЬ
Каждая строка однозначно относится к своей части
Строки неотличимы — отладка и фильтрация затруднены
Если запрос работает медленно, посмотрите план выполнения и замените ОБЪЕДИНИТЬ на ОБЪЕДИНИТЬ ВСЕ там, где дубли заведомо исключены. Также проверьте, что в каждой части используются виртуальные таблицы с параметрами отбора, а не полные таблицы регистров.
Часто задаваемые вопросы
Можно ли объединить больше двух запросов?
Да, операторы ОБЪЕДИНИТЬ и ОБЪЕДИНИТЬ ВСЕ можно перечислять подряд для любого практически разумного числа частей. Требования те же: совпадение количества полей, их порядка и совместимость типов во всех секциях. Допустимо смешивать операторы, но для читаемости лучше использовать один вариант во всём запросе.
Что быстрее — ОБЪЕДИНИТЬ или ОБЪЕДИНИТЬ ВСЕ?
ОБЪЕДИНИТЬ ВСЕ быстрее, потому что платформа не проверяет строки на совпадение. ОБЪЕДИНИТЬ требует дополнительной операции устранения дублей, которая на больших выборках заметно увеличивает время выполнения. Если дубли невозможны по логике данных, всегда выбирайте ОБЪЕДИНИТЬ ВСЕ.
Почему запрос с объединением выдаёт ошибку о несовпадении типов?
В одной и той же позиции полей части объединения содержат несовместимые типы — например, строку и число или ссылки на разные объекты там, где ожидался один тип. Найдите проблемную колонку, сравнив поля частей по позициям, и приведите значения к общему типу функцией ВЫРАЗИТЬ.
Чем объединение отличается от соединения таблиц?
Объединение складывает строки вертикально: результат содержит строки и первой, и второй выборки с одинаковым набором колонок. Соединение (ЛЕВОЕ, ВНУТРЕННЕЕ) сопоставляет строки двух таблиц по условию и склеивает их горизонтально, расширяя набор колонок. Это взаимодополняющие, а не взаимозаменяемые операции.
Как добавить в объединение строки, которых нет в источниках?
Используйте часть с выборкой констант без таблицы-источника: ВЫБРАТЬ «Итого» КАК Показатель, 0 КАК Значение. Такая секция объединяется с остальными по общим правилам и позволяет добавить служебные или пустые строки, например для шапки отчёта или значения по умолчанию.
Можно ли использовать объединение в запросе динамического списка?
Да, произвольный текст запроса динамического списка поддерживает ОБЪЕДИНИТЬ и ОБЪЕДИНИТЬ ВСЕ. Учтите ограничение: для корректной работы списка нужно указать основную таблицу или ключевое поле, а интерактивное изменение данных в таком списке может быть недоступно — обычно его делают только для чтения.
Что важно запомнить
Два запроса объединяются операторами ОБЪЕДИНИТЬ (уникальные строки) и ОБЪЕДИНИТЬ ВСЕ (все строки, быстрее). Части должны иметь одинаковое число полей в одном порядке с совместимыми типами; имена колонок задаёт первая часть. Проверяйте результат по числу строк и контрольным суммам.