Разработка отчетов на Системе компоновки данных (СКД) часто преподносит сюрпризы: запрос, который в консоли запросов выдает правильное количество строк, в самом отчете внезапно «схлопывает» данные или вовсе их теряет. Рассмотрим подробнее, почему это происходит, как работает внутренний механизм оптимизации СКД и что нужно сделать, чтобы отчет выводил данные корректно.
Главное отличие СКД от обычного выполнения запроса заключается в том, что система не отправляет в СУБД тот текст, который вы написали в конфигураторе. Перед исполнением Система компоновки данных анализирует настройки отчета (выбранные поля, группировки, отборы) и перестраивает текст запроса «на лету».
Этот процесс называется оптимизацией удаления неиспользуемых полей. Если в тексте вашего запроса во временной таблице или подзапросе выбирается десять полей, но в итоговом результате или в связях в настройках СКД реально используются только два, система просто вырежет остальные восемь из финального SQL-запроса для экономии ресурсов и ускорения работы. Проанализируем, к чему это приводит: если удаленные поля обеспечивали уникальность строк (например, разные номера документов при одной дате), то после их удаления строки станут идентичными и СКД их сгруппирует, уменьшив общее количество записей в отчете.
Разберем ситуацию, с которой столкнулся автор темы. В запросе использовались две временные таблицы. В одной из них (ВТ_2) выбирались три поля: Организация, Контрагент и Дата. Однако в результирующем запросе связь между ВТ_1 и ВТ_2 была настроена только по полю Дата.
Выясним причину странного поведения системы: так как поля Организация и Контрагент не использовались ни в связях, ни в выбранных полях финального отчета, оптимизатор СКД посчитал их лишними. В итоге запрос к ВТ_2 упростился до выбора одной только даты. Если в исходных данных было две строки с одной датой, но разными контрагентами, то после «оптимизации» осталась одна строка с этой датой. Это и привело к тому, что в консоли запросов (которая не делает таких оптимизаций) строк было две, а в СКД — одна.
Для исправления ситуации необходимо убедиться, что все поля, определяющие уникальность выборки, задействованы в связях. Пример правильной организации связи в тексте запроса:
ВЫБРАТЬ
Т1.Поле1,
Т2.Поле2
ИЗ
ВТ_1 КАК Т1
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_2 КАК Т2
ПО Т1.Дата = Т2.Дата
И Т1.Организация = Т2.Организация
И Т1.Контрагент = Т2.Контрагент
Иногда возникают ситуации, когда нам нужно сохранить структуру запроса и количество строк, даже если какие-то поля не выводятся пользователю напрямую. В конструкторе схемы компоновки данных на закладке «Наборы данных» для каждого поля предусмотрен флаг «Обязательное».
Посмотрим, как это работает на практике:
Обязательное для поля, СКД не сможет исключить его из запроса ни при каких обстоятельствах.Проанализируем еще одну настройку — «Автозаполнение». Когда этот флаг включен, СКД самостоятельно пытается определить роли полей (измерения, ресурсы, реквизиты). Если система ошибочно примет поле за реквизит, а не за измерение, она может некорректно построить итоговую выборку.
Рекомендуется проверять колонку «Роль» для ключевых полей:
Контрагент, Номенклатура), должны иметь роль Измерение.Без дублей.Период для соответствующих полей даты.Если вы видите, что данные в отчете не сходятся с ожиданиями, обычной консоли запросов недостаточно. Вам поможет инструмент «Консоль системы компоновки данных». В отличие от консоли запросов, она умеет показывать исполняемый запрос.
Рассмотрим пошагово процесс диагностики:
ГДЕ были выброшены системой.Важный совет: всегда обращайте внимание на то, как вы связываете временные таблицы. СКД — это не просто инструмент визуализации, а мощный генератор кода, который старается сделать запрос максимально легким для базы данных. Если вы не укажете системе, что данные важны для уникальности (через связи или флаг «Обязательное»), она их проигнорирует ради производительности.