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

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

Как убрать дубли в запросе 1С

Как убрать дубли в запросе 1С: конструкция РАЗЛИЧНЫЕ, группировка с агрегатами, причины задвоения строк при соединениях и способы проверить результат.

Дубли строк в результате запроса 1С — одна из самых частых проблем при построении отчётов и выборок. Они появляются из-за соединений таблиц с кратностью «один ко многим», лишних полей в выборке или ошибок в условиях связи. В зависимости от причины применяются разные приёмы: конструкция РАЗЛИЧНЫЕ, группировка с агрегатными функциями, исправление соединений или предварительная фильтрация во временной таблице.

Важно понимать, что механическое добавление ключевого слова РАЗЛИЧНЫЕ не всегда решает задачу. Если строки отличаются хотя бы в одном поле, они считаются разными, и дубли останутся. Поэтому сначала нужно выяснить, откуда взялись повторы, а уже потом выбирать инструмент.

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

Почему в запросе 1С появляются дубли

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

Вторая причина — избыточный набор полей в выборке. Если вы выбираете контрагента и одновременно договор, а у контрагента несколько договоров, то контрагент «задвоится». Формально строки разные, но с точки зрения бизнес-задачи это дубли.

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

Строки полностью одинаковыеИстинные дубли

Подойдёт РАЗЛИЧНЫЕ или группировка по всем полям

Повторяется только ключевое полеСвязь один-ко-многим

Проверьте соединения и условия связи

Суммы завышены в разыОшибочное соединение

Сравните итог с данными без соединения

Дубли только в части строкНеоднородные данные

Проверьте условия отбора и NULL в полях связи

Способ 1. Конструкция РАЗЛИЧНЫЕ

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

ВЫБРАТЬ РАЗЛИЧНЫЕ

Товары.Контрагент КАК Контрагент

ИЗ

Документ.РеализацияТоваровУслуг.Товары КАК Товары

Ключевое ограничение: РАЗЛИЧНЫЕ сравнивает всю строку целиком. Если вы добавите в выборку поле «Номенклатура», то один и тот же контрагент появится столько раз, сколько разных товаров ему продавали. Поэтому перед применением РАЗЛИЧНЫЕ уберите из выборки все поля, которые не нужны для итогового результата.

Есть и ограничение по типам данных: РАЗЛИЧНЫЕ нельзя применять, если среди полей выборки есть поля неограниченной длины (например, строки неограниченной длины) или поля типа ХранилищеЗначения. В таких случаях платформа выдаст ошибку, и придётся использовать группировку или выразить поле иначе.

Способ 2. Группировка через СГРУППИРОВАТЬ ПО

Группировка нужна, когда дублирующиеся строки содержат числовые данные, которые требуется свернуть: суммировать, посчитать количество, взять максимум или минимум. В этом случае поля, по которым определяется уникальность, перечисляются в СГРУППИРОВАТЬ ПО, а остальные оборачиваются в агрегатные функции.

ВЫБРАТЬ

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

СУММА(Продажи.Количество) КАК Количество,

СУММА(Продажи.Сумма) КАК Сумма

ИЗ

РегистрНакопления.Продажи КАК Продажи

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

Продажи.Номенклатура

Частая задача — получить уникальный список без агрегатов. Тогда по каждому негруппируемому полю применяют, например, МАКСИМУМ: это технически сворачивает дубли, хотя выглядит громоздко. Такой приём оправдан, когда РАЗЛИЧНЫЕ недоступно из-за типов полей.

Группировка также позволяет отфильтровать сами дубли: с помощью ИМЕЮЩИЕ можно оставить только те ключи, по которым больше одной строки, и таким образом найти проблемные данные, например задвоенные элементы справочника по совпадающему наименованию.

bsl
ВЫБРАТЬ Спр.Наименование, КОЛИЧЕСТВО(Спр.Ссылка) КАК Кол ИЗ Справочник.Номенклатура КАК Спр СГРУППИРОВАТЬ ПО Спр.Наименование ИМЕЮЩИЕ КОЛИЧЕСТВО(Спр.Ссылка) > 1

Способ 3. Устранение дублей при соединениях таблиц

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

Рабочий приём — сначала во временной таблице свернуть «множественную» сторону до одной строки на ключ, а потом соединять с основной выборкой. Например, сгруппировать регистр по контрагенту с МАКСИМУМ(Период), а затем по полученной паре «контрагент + период» забрать нужное значение. Так вы гарантируете кратность соединения один-к-одному.

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

Порядок действий при задвоении из-за соединения
  1. 1
    Определите, какое соединение порождает дубли: поочерёдно убирайте соединения и смотрите на результат
  2. 2
    Проверьте кратность связи: сколько записей правой таблицы приходится на одну запись левой
  3. 3
    Сверните правую таблицу во временной таблице до одной строки на ключ соединения
  4. 4
    Соедините основную выборку уже с свёрнутой временной таблицей
  5. 5
    Сверьте итоговые суммы с данными без соединения — они не должны измениться

Способ 4. Временные таблицы и предварительная фильтрация

Когда запрос сложный, удобно разбить его на этапы через временные таблицы (конструкция ПОМЕСТИТЬ). На промежуточном этапе можно применить РАЗЛИЧНЫЕ или группировку к небольшому набору полей, а затем уже к очищенным данным присоединять остальные реквизиты. Это и читаемее, и часто быстрее, чем один монолитный запрос.

Отдельный случай — дубли в самих данных, например два элемента справочника с одинаковым наименованием. Запросом такие дубли можно только скрыть в выборке, но не устранить. Для реальной чистки данных в типовых конфигурациях есть обработка «Поиск и удаление дублей» (в разделах администрирования), которая заменяет ссылки на дубли ссылкой на выбранный элемент и помечает лишние элементы на удаление.

Какой способ выбрать в разных ситуациях

Выбор инструмента зависит от того, что вы хотите получить на выходе. Если нужен просто уникальный список значений одного-двух полей — берите РАЗЛИЧНЫЕ. Если нужны свёрнутые показатели по уникальным ключам — группировку. Если дубли мешают в соединении и портят суммы — исправляйте само соединение через временную таблицу или виртуальные таблицы регистров.

В отчётах на СКД (системе компоновки данных) дубли часто убираются настройками группировок самого отчёта, без изменения текста запроса. Но если задвоение происходит на уровне набора данных, настройки СКД лишь замаскируют проблему, а итоги по ресурсам всё равно будут неверными.

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

РАЗЛИЧНЫЕ

Подходит для уникального списка без сумм. Ограничение: не работает с полями неограниченной длины и ХранилищеЗначения

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

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

Исправление соединения

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

Виртуальные таблицы регистров

Подходят для срезов и остатков: дублей нет по построению. Ограничение: только штатная структура регистра

Проверка результата и типичные ошибки

После доработки запроса результат нужно проверить, а не просто убедиться, что дубли визуально исчезли. Главный контроль — сверка итогов: сумма по числовому полю до и после устранения дублей должна совпадать с ожидаемым значением, если дубли были лишними, либо осознанно измениться, если строки сворачивались намеренно.

Полезный приём — подсчитать количество строк и количество уникальных ключей в результате: если они равны, дублей по ключу нет. В консоли запросов это делается быстро и не требует изменения основного текста.

Типичные ошибки
01
Добавление РАЗЛИЧНЫЕ при различающихся полях — дубли остаются, а время выполнения растёт
02
Группировка без агрегатной функции по числовому полю — платформа выдаёт ошибку или результат неожидан
03
Соединение с табличной частью без свёртки — суммы в отчёте завышаются кратно числу строк
04
Использование ЛЕВОЕ СОЕДИНЕНИЕ там, где нужно ВНУТРЕННЕЕ, — появляются строки с NULL, похожие на дубли
05
Удаление дублей элементов справочника без замены ссылок — битые ссылки в документах
Контрольные точки

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

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

Совпадает с числом уникальных ключей

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

Строк больше, чем уникальных ключей

Итоговые суммы
Норма

Совпадают с контрольными данными учёта

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

Суммы кратно завышены

Поля связи
Норма

Нет неожиданных NULL после соединений

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

Много NULL там, где ожидались значения

Скорость выполнения
Норма

Запрос выполняется за приемлемое время

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

РАЗЛИЧНЫЕ по большому набору полей заметно тормозит выборку

Частые вопросы

Чем РАЗЛИЧНЫЕ отличается от СГРУППИРОВАТЬ ПО?

РАЗЛИЧНЫЕ просто удаляет полностью одинаковые строки и не умеет ничего суммировать. Группировка объединяет строки по указанным полям и позволяет вычислять агрегаты — суммы, количества, максимумы. Если агрегаты не нужны, оба способа дадут одинаковый результат, но РАЗЛИЧНЫЕ обычно пишется короче.

Почему РАЗЛИЧНЫЕ не убирает дубли?

Значит, строки отличаются хотя бы в одном поле выборки. Уберите из запроса лишние поля либо перенесите их во временную таблицу, которую присоедините после получения уникального списка. Также проверьте, не отличаются ли значения незаметно — например, лишними пробелами в строках.

Как найти дубли в справочнике запросом?

Сгруппируйте элементы по полю совпадения (например, наименованию или ИНН) и с помощью ИМЕЮЩИЕ оставьте группы, где КОЛИЧЕСТВО(Ссылка) больше одного. Полученный список — кандидаты на объединение через штатную обработку поиска и удаления дублей.

Как убрать дубли в отчёте на СКД?

Сначала проверьте сам запрос набора данных: если задвоение там, исправляйте запрос. Если запрос корректен, а повторы видны в выводе, настройте группировки отчёта и уберите лишние поля из детальных строк. Для ресурсов проверьте выражения агрегирования на закладке «Ресурсы».

Влияет ли РАЗЛИЧНЫЕ на производительность?

Да, удаление дублей требует сортировки или хеширования результата, поэтому на больших выборках запрос с РАЗЛИЧНЫЕ работает медленнее. Сократите число полей и строк до применения РАЗЛИЧНЫЕ — например, сначала наложите отборы и поместите данные во временную таблицу.

Можно ли убрать дубли уже в готовой таблице значений в коде?

Да. Используйте метод Свернуть() с указанием колонок группировки и, при необходимости, колонок суммирования. Либо скопируйте нужные колонки в новую таблицу и сверните её — это аналог РАЗЛИЧНЫЕ для таблиц значений в памяти.

Итог

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

Дубли в запросе 1С убираются тремя путями: РАЗЛИЧНЫЕ для уникальных списков, группировка с агрегатами для свёртки с суммами и исправление соединений, когда задвоение рождается связью один-ко-многим. Всегда проверяйте итоговые суммы после доработки и не удаляйте дубли данных без замены ссылок.