Расчет недельных продаж с помощью DAX в LuckyTemplates
В этом руководстве показано, как в конечном итоге можно рассчитать разницу между еженедельными результатами продаж с помощью DAX в LuckyTemplates.
В этом руководстве мы рассмотрим фрагмент кода DAX. Возможно, вы уже использовали что-то подобное. Или вы можете столкнуться с этим и запутаться в том, как работает этот код и как контекст строки и контекст фильтра взаимодействуют друг с другом всего в одном коде DAX. В любом случае, в этом руководстве мы подробно рассмотрим все вышеперечисленное. Вы можете посмотреть полное видео этого урока в нижней части этого блога.
Во-первых, мы рассмотрим сам код. Затем мы перейдем к теоретической части, чтобы лучше понять ее. Наконец, мы рассмотрим все за кулисами с помощью DAX Studio .
Модель данных, которую мы собираемся использовать, представляет собой простую модель данных о продажах, содержащую даты, продажи и таблицу продуктов. Таблица «Продажи» содержит транзакции за каждый заданный день. Таблица «Продукты» содержит информацию о продажах продуктов в каждый заданный день. Таблица Dates содержит только несколько столбцов для целей этого руководства.
Нас интересует только таблица «Даты», но мы собираемся использовать таблицы «Продажи» и «Продукты», чтобы объяснить, как контекст фильтра и контекст строки распространяются с помощью отношений.
Оглавление
Контекст строки и контекст фильтра в промежуточном итоговом показателе
Теперь давайте создадим показатель промежуточного итога, так как он содержит контексты строк и фильтров. Это базовая мера промежуточного итога, в которой я использую COUNTROWS вместо FILTER и функцию ALL, чтобы вернуть все годы, которые у меня есть в таблице Date. Когда я приведу эту меру в таблицу ниже, вы увидите, что мы получаем ожидаемый результат.
Теперь давайте попробуем проанализировать, как работает этот код DAX.
В мере вы можете видеть, что сначала у нас есть COUNTROWS, но это не первая функция, которая оценивается или выполняется. Затем у нас есть функция ФИЛЬТР, а затем ВСЕ. Первым в порядке оценки стоит ВСЕ. ALL возвращает все уникальные значения номера года календаря Dates, игнорируя любой контекст фильтра, существующий за пределами функции ALL.
Итак, в метриках у нас есть столбец «Номер календарного года», и он активно фильтрует этот столбец. Но поскольку ALL будет игнорировать существующий контекст фильтра, мы получим все уникальные значения этого столбца.
Во втором аргументе, в контексте строки, мы написали, что число дат календарного года должно быть меньше, чем МАКСИМАЛЬНОЕ число дат календарного года. Теперь, если вы новичок и все еще пытаетесь понять и изучить DAX, вы можете подумать, что обе ссылки в левой части и внутри функции MAX относятся к одному и тому же столбцу и представляют собой одну и ту же таблицу, которую мы имеем внутри ВСЕ функции.
Но это неправда. Единственная часть контекста строки, принадлежащая функции ALL, — это та, которая находится слева. Тот, который у нас есть на MAX, оценивается внутри контекста фильтра, а не в контексте строки.
Итак, FILTER пытается создать контекст строки в таблице, которую вы указали в первом аргументе, и эта часть кода фактически извлекается из этого конкретного контекста строки. Таким образом, каждая строка FILTER повторяет ту таблицу, которая у нас есть внутри ALL, и тогда мы можем получить доступ ко всем значениям, которые мы в данный момент итерируем.
Итак, в первой итерации у нас есть только одно значение. Во второй итерации у нас есть второе значение. Но когда мы пишем MAX, оно не зависит от контекста строки, который мы создаем с помощью функции FILTER. Таким образом, MAX оценивается в контексте фильтра, созданного номером текущего года, который мы использовали в этой матрице.
Когда мы находимся в 2006, MAX вернет 2006, тогда как текущая строка может быть 2006, 2007 или 2008. ФИЛЬТР вернет таблицу, которая удовлетворяет критериям, которые мы указываем во втором аргументе. Когда мы перейдем к 2007 году, MAX вернет 2007. В 2008 году он вернет 2008. И в зависимости от всех значений, которые меньше значения, возвращаемого функцией MAX, ФИЛЬТР будет возвращать стол.
Чтобы доказать, что MAX не зависит от контекста строки, мы можем разделить этот фрагмент кода DAX на несколько переменных. И тогда мы сможем понять, что ссылка на столбец слева и справа не совпадает.
Итак, давайте создадим переменную.
Как вы можете видеть в приведенной ниже мере, я создал три переменные ( ). Затем я добавил код FILTER, наконец, с переменной Result, которая использует COUNTROWS . Когда я использую эту меру в таблице ниже, вы увидите, что ничего не меняется. Результаты все те же. Мы по-прежнему получаем ту же промежуточную сумму, что и раньше.
Если мы вернемся к коду и попытаемся получить значение первой переменной и подтвердим это, вы увидите, что для каждой строки мы получаем один и тот же год.
Итак, надеюсь, я смог объяснить вам, что функция MAX в этом конкретном коде на самом деле не зависит от реального контекста своих значений. И если вы хотите упростить свое понимание контекста оценки, вы всегда можете разбить код на несколько переменных, чтобы понять порядок оценки и то, как выполняется код.
Теперь я хочу показать вам сценарий, в котором функция MAX будет зависеть от контекста строки , созданного функцией FILTER.
Итак, вернемся к этой мере. Давайте продублируем это, и вместо последнего видимого года у меня будет MAX Dates Calendar Year Number. Когда я внесу это в матрицу, вы увидите, что мы получили пустое место.
Почему?
Дело в том, что мы повторяем все годы, а CALCULATE делает то, что он преобразует текущую итерируемую строку в эквивалентный контекст фильтра.
Если я поставлю здесь знак равенства, вы увидите, что мы получаем семь, семь и семь.
Почему?
Позвольте мне создать новую расчетную таблицу, чтобы вы могли легко понять, что происходит.
Пойду создавать новую таблицу. Затем я собираюсь написать над номером года календаря ВСЕХ дат. Затем я напишу Max Year, а затем я буду использовать CALCULATE поверх MAX числа дат календарного года. И теперь вы можете видеть, что для каждой строки мы повторяем одно и то же значение.
Поскольку эти числа строго не меньше самих себя, мы получаем пробел. Но когда мы используем равно (=), мы говорим, что все значения меньше 2011 получают семерку.
Более того, даже если вы используете ссылку на меру, такую как Max Year, этот код не будет работать.
Если я нажму подтвердить, вы увидите, что мы по-прежнему ничего не получаем. Это потому, что когда мы пишем Max Year, мы просто пишем CALCULATE MAX Dates Calendar Year Number.
Ссылка на меру всегда имеет вне нее CALCULATE. Таким образом, эта мера инициирует переход контекста, который преобразует текущую итерируемую строку в контекст фильтра.
Но если вы привязаны и вам нужно использовать ссылку на меру, вы можете сохранить эту меру в переменной. И, как вы, возможно, знаете, переменные постоянны, и они не могут создавать контекстный переход. Поэтому он не может преобразовать контекст строки в контекст фильтра.
Итак, это краткая демонстрация того, как контекст строки и контекст фильтра взаимодействуют друг с другом в коде DAX.
Теперь давайте отправимся в DAX Studio, чтобы понять, что происходит за кулисами.
Использование DAX Studio для понимания контекста строки и контекста фильтрации
Перейдем к внешним инструментам и запустим DAX Studio. Нам нужно подключиться к файлу LuckyTemplates с помощью Query Plan и Server Timings .
Затем я собираюсь создать меру запроса. Я напишу DEFINE MEASURE в таблице «Даты» «Даты текущего итога». И затем я собираюсь использовать исходный код, который у нас был.
Поскольку мы должны вернуть таблицу, мы можем написать EVALUATE. Наконец, мы собираемся создать таблицу, используя функцию SUMMARIZECOLUMNS. Итак, мы собираемся написать Даты Номер года календаря и виртуальный столбец, который будет промежуточным итогом. Затем я могу написать что-то вроде DT в качестве ключевого слова DAX Studio.
Если я выполню этот код, вы увидите, что код завершен, и мы по-прежнему получаем тот же результат, что и в LuckyTemplates.
Теперь давайте перейдем к плану запроса, чтобы понять, что происходит за кулисами. Давайте посмотрим, действительно ли функция MAX зависит от контекста строки или нет. Давайте перейдем к логическому плану запроса, потому что физический план запроса, как правило, более сложен и его немного трудно читать.
Вы можете видеть, что первым оператором в первой строке является GroupSemiJoin , и он используется SUMMARIZECOCOLUMNS для создания внутреннего соединения между двумя столбцами.
Затем для объединения этих столбцов есть Scan_Vertipaq , который является механизмом хранения, который у нас есть внутри служб анализа. Мы видим, что в нем говорится, что нам нужен столбец, который является номером года календаря дат. В LuckyTemplates вы можете видеть, что в матрице у нас есть столбец с номером календарного года, который действует как доступ к нашему отчету.
Затем у нас есть функция СЧЕТЧИКИ в нашей мере в качестве оператора верхнего уровня, затем СЧЕТЧИКИ вызывают функцию ФИЛЬТР для фильтра. Снова есть Scan_Vertipaq , в котором говорится, что RequiredCols — это номер года в календаре дат.
Строки 2 и 5 одинаковы, но первый Scan_Vertipaq помечен нулем, а второй — единицей. Это означает, что столбец, к которому мы обращаемся с помощью функции ALL, извлекается отдельно от столбца, который у нас есть внутри функции SUMMARIZECOLUMNS.
Затем есть оператор LessThan . В следующей строке мы видим, что происходит сравнение между контекстом строки и функцией MAX .
Далее следует Max_Vertipaq . Итак, мы фактически извлекаем значение Max из механизма хранения. Справа вы можете видеть, что он говорит: DependOnCols Dates Calendar Year Number. Это самое главное, что нам нужно помнить. Ранее я сказал, что нет никакой зависимости функции MAX от контекста строки, и это, собственно, и доказывает.
Так вот, здесь написано ноль.
Где мы нашли ноль?
Сверху (вторая строка), которая извлекается для СУММАРИЗИРОВАННЫХ КОЛОНН. Это означает, что функция MAX не зависит от контекста строки, но на самом деле она зависит от столбца (номер календарного года), который у нас есть внутри этой таблицы. Таким образом, эта таблица фактически создает контекст фильтра.
Короче говоря, функция MAX зависит от контекста фильтра, а не от контекста строки.
Далее вы можете видеть, что для вычисления Max_Vertipaq у нас есть Scan_Vertipaq , который говорит, что DependOnCols нулевой (0) номер календарного года даты. Кроме того, есть несколько других столбцов, для которых требуются столбцы.
Теперь давайте посмотрим на переменную версию кода. Вместо того, чтобы возвращать LastVisibleYear, я собираюсь вернуть версию COUNTROWS или переменную Result, и вы можете видеть, что мы по-прежнему получаем тот же результат.
Если мы посмотрим на план запроса, то увидим, что он немного длиннее, но его намного легче читать.
Наконец, вот также рассчитанная версия кода
А вот как выглядит его план логического запроса.
DAX LuckyTemplates: что такое контекст строки
Введение в фильтр контекста в LuckyTemplates
Что такое переход контекста и почему это важно?
Заключение
В этом руководстве я объяснил, как данная функция может и не может взаимодействовать с контекстом строки. Я также показал вам, как в этом случае MAX оценивался в контексте фильтра, а не в контексте строки.
Важно всегда помнить, что контекст фильтра фильтрует всю модель, а контекст строки выполняет только итерацию данной таблицы и никогда не фильтрует модель. Контекст фильтра не повторяет таблицу.
Я надеюсь, что вы нашли этот урок полезным. Следите за нашим кодом DAX Studio , который мы выпустим очень скоро. Мы углубимся в подобные сценарии. Мы также научим вас, как оптимизировать код DAX.
В этом руководстве показано, как в конечном итоге можно рассчитать разницу между еженедельными результатами продаж с помощью DAX в LuckyTemplates.
Что такое self в Python: примеры из реального мира
Вы узнаете, как сохранять и загружать объекты из файла .rds в R. В этом блоге также рассказывается, как импортировать объекты из R в LuckyTemplates.
В этом руководстве по языку программирования DAX вы узнаете, как использовать функцию GENERATE и как динамически изменять название меры.
В этом учебном пособии рассказывается, как использовать технику многопоточных динамических визуализаций для создания аналитических сведений из динамических визуализаций данных в ваших отчетах.
В этой статье я пройдусь по контексту фильтра. Контекст фильтра — одна из основных тем, с которой должен ознакомиться любой пользователь LuckyTemplates.
Я хочу показать, как онлайн-служба LuckyTemplates Apps может помочь в управлении различными отчетами и аналитическими данными, созданными из различных источников.
Узнайте, как рассчитать изменения вашей прибыли, используя такие методы, как разветвление показателей и объединение формул DAX в LuckyTemplates.
В этом руководстве будут обсуждаться идеи материализации кэшей данных и то, как они влияют на производительность DAX при предоставлении результатов.
Если вы все еще используете Excel до сих пор, то сейчас самое подходящее время, чтобы начать использовать LuckyTemplates для своих бизнес-отчетов.