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

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

ОБЪЕДИНИТЬ ВСЕ в запросе 1С: как работает объединение таблиц

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

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

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

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

Синтаксис и базовый пример объединения

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

ВЫБРАТЬ

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

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

ИЗ

Документ.ПриходнаяНакладная.Товары КАК Приход

ГДЕ

Приход.Ссылка.Проведен

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

ВЫБРАТЬ

Расход.Номенклатура,

-Расход.Количество

ИЗ

Документ.РасходнаяНакладная.Товары КАК Расход

ГДЕ

Расход.Ссылка.Проведен

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

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

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

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

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

Сравнение вариантов

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

Быстро, сохраняет все строки. Подходит, когда дубли невозможны по логике данных или нужны в результате.

ОБЪЕДИНИТЬ

Медленнее из-за устранения дублей. Нужен только когда части запроса могут вернуть одинаковые строки и повторы недопустимы.

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

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

Главное правило: количество полей во всех частях объединения должно совпадать, а типы значений в каждой позиции должны быть совместимы. Если в первой части поле имеет тип «СправочникСсылка.Номенклатура», а во второй — строка, платформа построит составной тип. Это работает, но усложняет дальнейшую обработку: соединения и отборы по составному полю выполняются медленнее, а в СКД могут возникнуть неожиданные ограничения.

Числовые поля с разной разрядностью приводятся к общему типу, однако лучше выравнивать типы явно с помощью функции ВЫРАЗИТЬ. Особенно это важно для строк: если в одной части строка неограниченной длины, а в другой — фиксированной, результат может обрезаться не так, как ожидал разработчик.

ВЫБРАТЬ

ВЫРАЗИТЬ("" КАК СТРОКА(100)) КАК Комментарий,

0 КАК Сумма

ИЗ

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

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

ВЫБРАТЬ

Операция.Комментарий,

Операция.Сумма

ИЗ

Документ.Операция КАК Операция

Если в какой-то части запроса поле отсутствует по смыслу, подставьте заглушку: NULL, 0, пустую строку или пустую ссылку через ЗНАЧЕНИЕ(). Заглушки делают структуру выборок одинаковой и позволяют объединить источники с разным набором реквизитов.

Объединение с временными таблицами и пакетные запросы

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

ВЫБРАТЬ

Движения.Номенклатура КАК Номенклатура,

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

ПОМЕСТИТЬ ВТ_Обороты

ИЗ

(ВЫБРАТЬ

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

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

ИЗ

Документ.ПриходнаяНакладная.Товары КАК Приход

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

ВЫБРАТЬ

Расход.Номенклатура,

-Расход.Количество

ИЗ

Документ.РасходнаяНакладная.Товары КАК Расход) КАК Движения

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

Движения.Номенклатура

;

Внутри вложенного запроса объединение работает точно так же, как на верхнем уровне. Обратите внимание: группировка выполняется уже после объединения, поэтому суммы корректно сворачиваются по номенклатуре независимо от того, из какого документа пришла строка.

Конструктор запроса в конфигураторе умеет строить объединения визуально: на закладке «Объединения/Псевдонимы» добавляются запросы-участники, а платформа сама контролирует соответствие полей. Для сложных случаев это удобная проверка перед ручной доработкой текста.

Производительность: что проверить до и после

Объединение само по себе не является узким местом — проблемы обычно создают источники данных и последующая обработка. Тем не менее несколько правил помогают избежать типичных просадок. Во-первых, отборы накладывайте в каждой части объединения, а не после него: чем меньше строк попадает в объединённый поток, тем быстрее весь запрос.

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

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

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

Количество строк результата
Норма

Равно сумме строк всех частей (для ОБЪЕДИНИТЬ ВСЕ)

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

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

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

Поля имеют ожидаемые типы, отборы и соединения работают

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

Появился составной тип, соединения тормозят

Суммы после группировки
Норма

Сходятся с контрольными данными из источников

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

Суммы удвоены — данные продублированы в частях объединения

Проверить план выполнения можно через технологический журнал или средства СУБД. Если запрос с объединением стал работать медленнее после обновления платформы или роста данных, первым делом смотрите, не появилась ли операция сортировки в плане — это признак лишнего устранения дублей или группировки не по индексированным полям.

Типичные ошибки при использовании объединений

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

Отдельно стоит упомянуть итоги. Конструкция ИТОГИ применяется ко всему результату объединения, а не к отдельным частям. Если нужны промежуточные итоги по каждому источнику, добавьте в каждую часть поле-маркер (например, строку «Приход» или «Расход») и группируйте по нему — так вы получите и разбивку, и общий итог одним запросом.

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

Итог

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

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

Частые вопросы об объединении в запросах 1С

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

Жёсткого документированного ограничения нет, но на практике запросы с более чем несколькими десятками объединений становятся тяжёлыми для анализа оптимизатором СУБД и для сопровождения. Если частей много, рассмотрите сборку данных во временные таблицы по этапам.

Можно ли упорядочить каждую часть объединения по-разному?

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

Почему после объединения исчезли часть строк?

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

Что быстрее: объединение или соединение?

Это разные операции для разных задач: объединение добавляет строки, соединение — колонки. Сравнивать их по скорости некорректно. Если задача — собрать однотипные данные из нескольких источников, нужно объединение; если дополнить строки данными из другой таблицы — соединение.

Можно ли объединять таблицы значений, загруженные через параметр?

Да. Таблицу значений передают в запрос параметром, помещают во временную таблицу через ВЫБРАТЬ ... ИЗ &Таблица, а дальше объединяют с любыми другими источниками по обычным правилам. Состав колонок параметра-таблицы должен совпадать с полями выборки.

Работает ли ОБЪЕДИНИТЬ ВСЕ в СКД?

Да, в наборе данных типа «Запрос» системы компоновки данных объединения поддерживаются полностью. Учитывайте только, что поля ресурсов и их типы определяются по первой части объединения, а составные типы могут ограничить доступные варианты группировок в настройках отчёта.