Почему оператор РАЗЛИЧНЫЕ в СКД работает некорректно и как это исправить?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке отчетов на базе Системы компоновки данных (СКД) разработчики часто сталкиваются с ситуацией, когда запрос, идеально работающий в Консоли запросов, в рамках отчета выдает совершенно иные результаты. Одной из самых частых причин такого поведения является агрессивная оптимизация, которую проводит СКД при формировании итогового SQL-запроса к базе данных.

Давайте разберемся, почему это происходит и какими способами можно заставить систему работать так, как мы ожидаем.

Суть проблемы: невидимая оптимизация СКД

Когда мы пишем запрос в Консоли запросов, система исполняет его в точности так, как мы его написали. Однако СКД — это надстройка. Перед тем как отправить запрос к серверу баз данных, СКД анализирует настройки отчета: выбранные поля, группировки, отборы и ресурсы. Если какое-то поле, присутствующее в исходном запросе (даже внутри предложения СГРУППИРОВАТЬ ПО), не выводится в отчет и не участвует в расчетах, СКД «вырезает» его из итогового запроса для повышения производительности.

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

Способ №1: Установка свойства «Обязательное»

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

  1. Перейдите на вкладку Наборы данных в настройках СКД.
  2. В списке полей найдите нужное поле (например, Контрагент).
  3. Откройте свойства этого поля.
  4. Установите флаг Обязательное.

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

Способ №2: Использование вложенных запросов

Если по какой-то причине использование свойств полей кажется неудобным или ситуация требует более жесткой изоляции логики, мы можем «спрятать» группировку от оптимизатора СКД с помощью вложенных запросов или временных таблиц. Суть метода заключается в том, чтобы выполнить группировку на внутреннем уровне, а СКД предоставить уже готовый набор данных.

Рассмотрим на примере:


ВЫБРАТЬ
    Т.Ответственный,
    Т.Дата,
    СУММА(1) КАК Количество
ПОМЕСТИТЬ ТКоличествоКлиентов
ИЗ
    (ВЫБРАТЬ
        Т.Ответственный КАК Ответственный,
        Т.Контрагент КАК Контрагент,
        Т.Дата КАК Дата
    ИЗ
        ТКасса КАК Т
    ГДЕ
        Т.Дата МЕЖДУ &НачалоПериода И &КонецПериода
    СГРУППИРОВАТЬ ПО
        Т.Ответственный,
        Т.Контрагент,
        Т.Дата) КАК Т
СГРУППИРОВАТЬ ПО
    Т.Ответственный,
    Т.Дата

В данном примере СКД видит подзапрос как источник, в котором уже проведена вся необходимая обработка. Оптимизатор не будет пытаться «пролезть» внутрь вложенного запроса, чтобы убрать поле Контрагент, так как оно участвует в логике формирования временной таблицы.

Способ №3: Отключение автозаполнения

Радикальным методом решения является полное отключение Автозаполнения наборов данных. Если мы снимем этот флаг в настройках набора данных, СКД перестанет пытаться оптимизировать состав полей в запросе, полагаясь исключительно на то, что мы написали вручную.

Однако помните: этот метод требует от разработчика высокой квалификации и дисциплины. При отключенном Автозаполнении вам придется:

Этот путь стоит выбирать только тогда, когда стандартные механизмы СКД вступают в неразрешимый конфликт с вашей бизнес-логикой.

Подведем итоги

Проблема «неправильной» работы РАЗЛИЧНЫЕ — это не баг платформы, а закономерный результат автоматизации. Чтобы отчет работал корректно:

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

← На главную