Почему текст запроса в СКД отличается от консоли запросов и как это исправить?

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

При работе с Системой компоновки данных (СКД) разработчики часто сталкиваются с ситуацией, когда один и тот же запрос выдает разные результаты в консоли запросов и в отчете. Чаще всего это проявляется в "схлопывании" строк или исчезновении целых полей из секции ВЫБРАТЬ и СГРУППИРОВАТЬ ПО. Разберем подробно, почему это происходит и как заставить СКД выполнять запрос именно в том виде, в котором он был задуман.

Выясняем причину: как работает оптимизатор СКД

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

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

Рассмотрим пример проблемного запроса из практики:


ВЫБРАТЬ РАЗРЕШЕННЫЕ
    ВТ_Товары.Ссылка КАК Ссылка,
    ВТ_Товары.Номенклатура КАК Номенклатура,
    ВТ_Товары.Количество КАК Количество,
    МАКСИМУМ(ЕСТЬNULL(ЗаказПоставщикуОсновная.ЦенаDDP, 0)) КАК СуммаDDPУпр
ПОМЕСТИТЬ ВТ_ЦеныУпр
ИЗ
    ВТ_Товары КАК ВТ_Товары
        ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказПоставщику.Основная КАК ЗаказПоставщикуОсновная
        ПО ВТ_Товары.Счет.ДокОснование = ЗаказПоставщикуОсновная.Ссылка.ДокОснование
            И ВТ_Товары.Номенклатура = ЗаказПоставщикуОсновная.Номенклатура
СГРУППИРОВАТЬ ПО
    ВТ_Товары.Ссылка,
    ВТ_Товары.Номенклатура,
    ВТ_Товары.Количество

Если СКД решит, что поле Номенклатура не нужно для финального отображения, она исключит его из группировки, и результат во временной таблице ВТ_ЦеныУпр станет некорректным.

Решение 1: Установка роли «Обязательное»

Наиболее правильный и надежный способ зафиксировать поле в запросе — это использование ролей полей набора данных. Разберем по шагам, как это сделать:

  1. Откроем конструктор схемы компоновки данных и перейдем на закладку Наборы данных.
  2. Найдем в списке полей то, которое "исчезает" (в нашем примере это Номенклатура).
  3. В колонке Роль нажмем на кнопку выбора.
  4. В открывшемся окне установим флаг Обязательное (Mandatory).

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

Решение 2: Использование флага «Использовать всегда»

Существует еще один механизм, который часто путают с ролями — это настройка компоновки Использовать всегда. Рассмотрим, чем она отличается:

Решение 3: Отключение автозаполнения

Рассмотрим радикальный метод — снятие флага Автозаполнение в нижней части окна конструктора запроса СКД. Посмотрим, что произойдет в этом случае:

Как проанализировать итоговый запрос?

Чтобы окончательно убедиться в том, какой именно запрос отправляется в базу данных, рекомендуем использовать Консоль системы компоновки данных (внешняя обработка с ИТС). Она позволяет увидеть:

Проанализировав исполняемый запрос, вы сразу увидите, в каком месте СКД "вырезала" поля и где необходимо применить роль Обязательное.

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

← На главную