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