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