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