При разработке отчетов в системе компоновки данных (СКД) разработчики часто сталкиваются с дилеммой: написать один большой монолитный запрос с несколькими соединениями таблиц или разделить выборку на отдельные наборы данных и связать их на вкладке Связи наборов данных. На первый взгляд, традиционное соединение на уровне СУБД кажется более привычным, однако механизм связывания наборов данных в СКД решает целый ряд специфических архитектурных и прикладных задач. Разберем детально, когда и почему целесообразно использовать раздельные наборы данных.
Проанализируем классическую проблему реляционных СУБД: при соединении таблиц с разным уровнем детализации (например, «один ко многим») данные из таблицы верхнего уровня неизбежно дублируются. Если мы соединяем документ и строки его табличной части обычным левым соединением в запросе, то сумма шапки документа повторится столько раз, сколько строк содержится в его табличной части. При попытке рассчитать общую сумму в отчете стандартная функция суммирования вернет искаженное значение.
Для решения этой проблемы в СКД применяется разделение данных:
НаборДанныхДокументы) мы выбираем реквизиты шапки документа и его общую сумму.НаборДанныхСостав) выбираем строки табличной части с номенклатурой и количеством.Ссылка.В этом случае процессор компоновки данных обрабатывает агрегацию ресурсов независимо для каждого уровня группировки. Итоги по шапке документа считаются строго по первому набору, исключая задвоение сумм, а детализация строится корректно по второму набору.
Рассмотрим ситуацию, когда для получения данных из второй таблицы необходимо динамически передавать значение, рассчитанное в первой таблице. В классическом тексте запроса платформы 1С невозможно организовать прямой коррелированный подзапрос, который принимал бы значение текущей строки внешнего запроса в качестве параметра условия среза последних или виртуальной таблицы.
Механизм связей наборов данных СКД предоставляет колонку Параметры. Мы можем связать источник и приемник так, чтобы поле из первого набора передавалось непосредственно в параметр второго запроса. Это незаменимо в следующих сценариях:
&Период виртуальной таблицы среза регистра из второго набора.Посмотрим на поведение платформы при выводе отчета пользователем. Если мы строим отчет на базе одного огромного запроса со множеством соединений, СУБД всегда выполняет план запроса целиком, обращаясь ко всем соединенным таблицам — даже если пользователь настроил вариант отчета, где поля из половины таблиц вообще не выводятся.
СКД применяет интеллектуальный анализ используемых полей:
При соединении таблиц в тексте запроса через оператор ПО разработчик ограничен синтаксисом языка запросов 1С:Предприятия. При связывании наборов данных в СКД поля Выражение источника и Выражение приемника поддерживают полный синтаксис языка выражений СКД.
Это позволяет сопоставлять поля с предварительной обработкой на лету: проверять типы, использовать условные конструкции ВЫБОР, строковые операции и вызовы системных функций без перегрузки текстов базовых запросов сложными преобразованиями.
Выясним еще одно важное преимущество: сопровождение сложных отчетов. Когда один отчет объединяет учет остатков, взаиморасчеты, данные планирования и плановые цены, написание одного запроса на десятки подзапросов и временных таблиц делает его монолитным и трудночитаемым.
Разделение на отдельные логические наборы данных позволяет:
Проанализируем техническую сторону работы нескольких наборов данных, чтобы избежать типичных ошибок производительности:
Таким образом, разделение на наборы данных является мощным инструментом, который незаменим для корректного подсчета разноуровневых итогов, построения иерархий и параметризованных выборок, но должен применяться осознанно с учетом объемов результирующих данных.