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