При разработке отчетов в Системе Компоновки Данных (СКД) часто возникает задача горизонтального разворачивания данных. Напримере справочника или регистра с полями Этап, Подэтап и Компонент требуется вывести разные компоненты одной пары этапа и подэтапа в соседних колонках одной строки.
Рассмотри подробно несколько эффективных способов решения этой задачи: разворот данных средствами настройки структуры отчета (кросс-таблица), самосоединение таблицы в запросе и условная агрегация.
Самый простой и гибкий способ получить требуемый вид отчета без усложнения запроса — использование элемента структуры отчета Таблица (кросс-таблица).
Разберем по шагам порядок настройки схемы компоновки данных:
Этап и Подэтап.Компонент.Максимум(Компонент), Сумма(Сумма_USD) и Сумма(Сумма_EUR).При таком подходе система динамически сформирует столько колонок компонентов, сколько их зарегистрировано в базе данных для текущей пары этапа и подэтапа.
Если плоскую структуру колонок необходимо получить непосредственно в результате выполнения запроса (например, для обработки в коде или выгрузки в другие системы), задействуем левое соединение временной таблицы с самой собой.
Проанализируем ключевое правило: чтобы исключить дублирование записей (декартово произведение), необходимо связать таблицы по полям Этап и Подэтап, а также явно указать целевое значение компонента для каждого соединения.
Рассмотрим пример построения запроса:
ВЫБРАТЬ
ИсходныеДанные.Этап КАК Этап,
ИсходныеДанные.Подэтап КАК Подэтап,
ИсходныеДанные.Компонент КАК Компонент,
ИсходныеДанные.Сумма_USD КАК Сумма_USD,
ИсходныеДанные.Сумма_EUR КАК Сумма_EUR
ПОМЕСТИТЬ ВТ_ИсходныеДанные
ИЗ
Справочник.СправочникЭтапов КАК ИсходныеДанные
;
ВЫБРАТЬ РАЗЛИЧНЫЕ
ВТ.Этап КАК Этап,
ВТ.Подэтап КАК Подэтап
ПОМЕСТИТЬ ВТ_Ключи
ИЗ
ВТ_ИсходныеДанные КАК ВТ
;
ВЫБРАТЬ
Ключи.Этап КАК Этап1,
Ключи.Подэтап КАК Подэтап1,
Т1.Компонент КАК Компонент1,
Т1.Сумма_USD КАК Сумма_USD1,
Ключи.Этап КАК Этап2,
Ключи.Подэтап КАК Подэтап2,
Т2.Компонент КАК Компонент2,
Т2.Сумма_USD КАК Сумма_USD2,
Ключи.Этап КАК Этап3,
Ключи.Подэтап КАК Подэтап3,
Т3.Компонент КАК Компонент3,
Т3.Сумма_USD КАК Сумма_USD3
ИЗ
ВТ_Ключи КАК Ключи
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ИсходныеДанные КАК Т1
ПО Ключи.Этап = Т1.Этап
И Ключи.Подэтап = Т1.Подэтап
И Т1.Компонент = "A"
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ИсходныеДанные КАК Т2
ПО Ключи.Этап = Т2.Этап
И Ключи.Подэтап = Т2.Подэтап
И Т2.Компонент = "B"
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ИсходныеДанные КАК Т3
ПО Ключи.Этап = Т3.Этап
И Ключи.Подэтап = Т3.Подэтап
И Т3.Компонент = "C"
Если список компонентов фиксирован и заранее известен (например, «A», «B», «C»), оптимальным решением с точки зрения производительности СУБД будет использование условной агрегации с группировкой по полям Этап и Подэтап.
Разберем пример запроса с условным выбором:
ВЫБРАТЬ
ИсходныеДанные.Этап КАК Этап,
ИсходныеДанные.Подэтап КАК Подэтап,
МАКСИМУМ(ВЫБОР КОГДА ИсходныеДанные.Компонент = "A" ТОГДА ИсходныеДанные.Компонент ИНАЧЕ "" КОНЕЦ) КАК Компонент1,
СУММА(ВЫБОР КОГДА ИсходныеДанные.Компонент = "A" ТОГДА ИсходныеДанные.Сумма_USD ИНАЧЕ 0 КОНЕЦ) КАК Сумма_USD1,
МАКСИМУМ(ВЫБОР КОГДА ИсходныеДанные.Компонент = "B" ТОГДА ИсходныеДанные.Компонент ИНАЧЕ "" КОНЕЦ) КАК Компонент2,
СУММА(ВЫБОР КОГДА ИсходныеДанные.Компонент = "B" ТОГДА ИсходныеДанные.Сумма_USD ИНАЧЕ 0 КОНЕЦ) КАК Сумма_USD2,
МАКСИМУМ(ВЫБОР КОГДА ИсходныеДанные.Компонент = "C" ТОГДА ИсходныеДанные.Компонент ИНАЧЕ "" КОНЕЦ) КАК Компонент3,
СУММА(ВЫБОР КОГДА ИсходныеДанные.Компонент = "C" ТОГДА ИсходныеДанные.Сумма_USD ИНАЧЕ 0 КОНЕЦ) КАК Сумма_USD3
ИЗ
Справочник.СправочникЭтапов КАК ИсходныеДанные
ГРУППИРОВАТЬ ПО
ИсходныеДанные.Этап,
ИсходныеДанные.Подэтап
Выбор конкретного метода зависит от требований к отчету: для работы с неизвестным заранее количеством компонентов рекомендуется использовать встроенную кросс-таблицу СКД, а для фиксированного перечня полей — условную агрегацию в запросе.