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