При работе с Системой компоновки данных (СКД) разработчики часто сталкиваются с ситуацией, когда один и тот же запрос выдает разные результаты в консоли запросов и в отчете. Чаще всего это проявляется в "схлопывании" строк или исчезновении целых полей из секции ВЫБРАТЬ и СГРУППИРОВАТЬ ПО. Разберем подробно, почему это происходит и как заставить СКД выполнять запрос именно в том виде, в котором он был задуман.
В отличие от обычной консоли, СКД не выполняет запрос "как есть". Платформа анализирует настройки отчета — выбранные поля, группировки, отборы — и на их основе динамически перестраивает исходный текст для повышения производительности. Этот механизм называется оптимизацией запроса.
Проанализируем ситуацию: если в вашем запросе (особенно во временных таблицах) есть поле, которое используется для группировки, но оно не выводится в финальный результат и не участвует в отборах, СКД может посчитать его "лишним". В итоге поле удаляется из секции СГРУППИРОВАТЬ ПО, что приводит к изменению итогового количества строк во временной таблице. Данные объединяются (агрегируются) сильнее, чем планировал разработчик.
Рассмотрим пример проблемного запроса из практики:
ВЫБРАТЬ РАЗРЕШЕННЫЕ
ВТ_Товары.Ссылка КАК Ссылка,
ВТ_Товары.Номенклатура КАК Номенклатура,
ВТ_Товары.Количество КАК Количество,
МАКСИМУМ(ЕСТЬNULL(ЗаказПоставщикуОсновная.ЦенаDDP, 0)) КАК СуммаDDPУпр
ПОМЕСТИТЬ ВТ_ЦеныУпр
ИЗ
ВТ_Товары КАК ВТ_Товары
ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказПоставщику.Основная КАК ЗаказПоставщикуОсновная
ПО ВТ_Товары.Счет.ДокОснование = ЗаказПоставщикуОсновная.Ссылка.ДокОснование
И ВТ_Товары.Номенклатура = ЗаказПоставщикуОсновная.Номенклатура
СГРУППИРОВАТЬ ПО
ВТ_Товары.Ссылка,
ВТ_Товары.Номенклатура,
ВТ_Товары.Количество
Если СКД решит, что поле Номенклатура не нужно для финального отображения, она исключит его из группировки, и результат во временной таблице ВТ_ЦеныУпр станет некорректным.
Наиболее правильный и надежный способ зафиксировать поле в запросе — это использование ролей полей набора данных. Разберем по шагам, как это сделать:
Номенклатура).Флаг Обязательное сообщает оптимизатору СКД, что данное поле должно присутствовать в SQL-запросе всегда, даже если пользователь не выбрал его в настройках отчета. Это гарантирует сохранение структуры группировки во временных таблицах.
Существует еще один механизм, который часто путают с ролями — это настройка компоновки Использовать всегда. Рассмотрим, чем она отличается:
Рассмотрим радикальный метод — снятие флага Автозаполнение в нижней части окна конструктора запроса СКД. Посмотрим, что произойдет в этом случае:
Чтобы окончательно убедиться в том, какой именно запрос отправляется в базу данных, рекомендуем использовать Консоль системы компоновки данных (внешняя обработка с ИТС). Она позволяет увидеть:
Проанализировав исполняемый запрос, вы сразу увидите, в каком месте СКД "вырезала" поля и где необходимо применить роль Обязательное.
Резюме: Если СКД меняет логику вашего запроса, не спешите отключать автозаполнение. Проверьте роли полей и установите признак Обязательное для тех измерений, которые формируют уникальность строк в ваших временных таблицах.