Поделиться через


Использование переменных для улучшения формул DAX

В качестве моделиировщика данных написание и отладка некоторых вычислений DAX может быть сложной задачей. Обычно сложные требования к вычислению часто включают написание составных или сложных выражений. Составные выражения могут включать использование многих вложенных функций и, возможно, повторное использование логики выражений.

Использование переменных в формулах DAX позволяет создавать более сложные и эффективные вычисления. Переменные могут повысить производительность, надежность, удобочитаемость и уменьшить сложность.

В этой статье мы продемонстрируем первые три преимущества, используя пример меры для роста продаж по сравнению с годом (YoY). (Формула роста продаж YoY — это период продаж, минус продажи за тот же период прошлого года, разделенный на продажи за тот же период прошлого года.)

Начнем со следующего определения меры.

Sales YoY Growth % =
DIVIDE(
    ([Sales] - CALCULATE([Sales], PARALLELPERIOD('Date'[Date], -12, MONTH))),
    CALCULATE([Sales], PARALLELPERIOD('Date'[Date], -12, MONTH))
)

Мера создает правильный результат, но теперь давайте посмотрим, как его можно улучшить.

Повышение производительности

Обратите внимание, что формула повторяет выражение, вычисляющее "тот же период прошлого года". Эта формула неэффективна, так как для вычисления одного выражения в два раза требуется Power BI. Определение меры можно сделать более эффективным с помощью переменной VAR.

Следующее определение меры представляет улучшение. Он использует выражение для назначения результата "того же периода в прошлом году" переменной с именем SalesPriorYear. Затем переменная используется дважды в выражении RETURN.

Sales YoY Growth % =
VAR SalesPriorYear =
    CALCULATE([Sales], PARALLELPERIOD('Date'[Date], -12, MONTH))
RETURN
    DIVIDE(([Sales] - SalesPriorYear), SalesPriorYear)

Мера продолжает создавать правильный результат и делает это около половины времени запроса.

Улучшение удобочитаемости

В определении предыдущей меры обратите внимание, что выбор имени переменной упрощает выражение RETURN. Выражение является коротким и самоописывющим.

Упрощение отладки

Переменные также могут помочь выполнить отладку формулы. Чтобы проверить выражение, назначенное переменной, временно перезаписываете выражение RETURN, чтобы вывести переменную.

Следующее определение меры возвращает только переменную SalesPriorYear . Обратите внимание, как оно примечает предполагаемое выражение RETURN. Этот метод позволяет легко отменить изменения обратно после завершения отладки.

Sales YoY Growth % =
VAR SalesPriorYear =
    CALCULATE([Sales], PARALLELPERIOD('Date'[Date], -12, MONTH))
RETURN
    --DIVIDE(([Sales] - SalesPriorYear), SalesPriorYear)
    SalesPriorYear

Упрощение работы

В более ранних версиях DAX переменные пока не поддерживаются. Сложные выражения, вносившие новые контексты фильтра, должны были использовать функции БОЛЕЕ РАННИХ или РАННИХ DAX для ссылки на контексты внешнего фильтра. К сожалению, моделиторы данных обнаружили, что эти функции трудно понять и использовать.

Переменные всегда вычисляются вне фильтров, которые применяется выражение RETURN. По этой причине при использовании переменной в измененном контексте фильтра он достигает того же результата, что и функция EARLIEST. Поэтому можно избежать использования функций БОЛЕЕ РАННИХ или РАННИХ версий. Это означает, что теперь можно писать формулы, которые являются менее сложными, и это проще понять.

Рассмотрим следующее определение вычисляемого столбца, добавленное в таблицу Подкатегории . Он оценивает ранг для каждого подкатегории продукта на основе значений столбца Subcategory Sales .

Subcategory Sales Rank =
COUNTROWS(
    FILTER(
        Subcategory,
        EARLIER(Subcategory[Subcategory Sales]) < Subcategory[Subcategory Sales]
    )
) + 1

Функция РАНЕЕ используется для ссылки на значение столбца Subcategory Sales в текущем контексте строки.

Определение вычисляемого столбца можно улучшить с помощью переменной вместо функции РАНЕЕ. Переменная CurrentSubcategorySales сохраняет значение столбца Subcategory Sales в текущем контексте строки, а выражение RETURN использует его в измененном контексте фильтра.

Subcategory Sales Rank =
VAR CurrentSubcategorySales = Subcategory[Subcategory Sales]
RETURN
    COUNTROWS(
        FILTER(
            Subcategory,
            CurrentSubcategorySales < Subcategory[Subcategory Sales]
        )
    ) + 1