Image

Под капотом: как DAX работает с фильтрами

Объединение функций Time Intelligence для иллюстрации логики применения фильтров DAX и управления ими

Делиться

728354107403fcae2649fdda19bc32b8

Введение

Начнем с простой таблицы:

463260c16dbecb2c226915725a1ccf38

Каждая строка в матрице отображает общий объем онлайн-продаж за каждый месяц.
Все идет нормально.

Интерпретация заключается в том, что мы видим общий объем онлайн-продаж, отфильтрованный по месяцам.

Но это не вся правда.

Давайте посмотрим на модель данных:

fdca350c9611c4a0d29122bb3a1628da

Если вы посмотрите внимательно, то увидите, что между двумя столбцами дат выстроена связь.

Связи со столбцом «Месяц» нет.

Если мы пойдем этим путем, то приведенная выше интерпретация будет не совсем точной.

Полная интерпретация должна быть такой: каждая строка показывает общий объём онлайн-продаж, отфильтрованный по таблице дат. Строки таблицы дат сгруппированы по месяцам. Каждая строка показывает общий объём продаж за все дни каждого месяца.

Когда мы осознаем эту деталь, мы станем на шаг ближе к пониманию DAX в целом и функций временной аналитики в частности.

Давайте сделаем еще один шаг вперед.

YTD и базовый запрос

Теперь давайте добавим показатель YTD, чтобы посмотреть, что произойдет:

48c282a8a705ec19887d667d5838e404

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

Теперь давайте посмотрим, что именно делает функция DATESYTD().

В пояснении от dax.guide говорится: «Возвращает набор дат в году до последней даты, видимой в контексте фильтра».

Что именно это означает?

Чтобы разобраться в этом вопросе, давайте сначала напишем запрос DAX, чтобы получить список дат в июне 2024 года, как это сделано в визуализации выше:

DEFINE VAR YearFilter = TREATAS({ 2024 }, 'Дата'[Год]) VAR MonthFilter = TREATAS({ 6 }, 'Дата'[Месяц]) EVALUATE SUMMARIZECOLUMNS('Дата'[Дата],YearFilter,MonthFilter)

В результате получается список из 30 дней июня:

06411b2a9984052f894421cb775f7bae

Это фильтр, примененный к строке за июнь 2024 г. в матрице, показанной выше.

Какой результат получим, если применить функцию DATESYTD() к результату?

Вот запрос:

DEFINE VAR YearFilter = TREATAS({ 2024 }, 'Дата'[Год]) VAR MonthFilter = TREATAS({ 6 }, 'Дата'[Месяц]) VAR BasisDates = CALCULATETABLE( SUMMARIZECOLUMNS('Дата'[Дата],YearFilter,MonthFilter) ) VAR YTDDates = DATESYTD(TREATAS(BasisDates, 'Дата'[Дата]) ) EVALUATE YTDDates

И вот, результат:

db93dc4763dbc9205b8d5eb70fa68aec

Это список из 182 строк, содержащий все даты с начала года до последнего дня июня 2024 года.

Это определение YTD.

Если взглянуть на следующую меру:

Онлайн-продажи (YTD) = VAR YTDDates = DATESYTD('Дата'[Дата]) RETURN CALCULATE([Сумма онлайн-продаж] ,YTDDates )

Мы понимаем, что переменная YTDDates — это «всего лишь» список дат, примененный в качестве фильтра к функции CALCULATE().

Это ключ ко всем функциям интеллекта Времени.

Вернитесь на год назад — несколько примеров

Что произойдет, если к результату применить другую функцию?

Например, SAMEPERIODLASTYEAR()?

Чтобы ответить на этот вопрос, я использую следующий запрос DAX:

DEFINE VAR YearFilter = TREATAS({ 2024 }, 'Дата'[Год]) VAR MonthFilter = TREATAS({ 6 }, 'Дата'[Месяц]) VAR BasisDates = CALCULATETABLE( SUMMARIZECOLUMNS('Дата'[Дата],YearFilter,MonthFilter ) ) VAR YTDDates = DATESYTD(TREATAS(BasisDates, 'Дата'[Дата]) ) VAR YTDDatesPY = SAMEPERIODLASTYEAR(YTDDates) EVALUATE YTDDatesPY

Я намеренно отделил вызов SAMEPERIODLASTYEAR() от DATESYTD() для удобства чтения. Можно было бы вложить DATESYTD() в SAMEPERIODLASTYEAR().

На этот раз у нас 181 строка, поскольку 2024 год был високосным.
И даты сдвинуты на один год назад:

52738d424fcf977dc0c0ae6d43a39574

Итак, снова, когда мы применяем функцию Time Intelligence к мере, функция, например, DATESYTD(), возвращает список дат.
Обратите внимание: при применении фильтра все существующие фильтры в таблице дат удаляются.

Пользовательская логика

Теперь давайте применим эти знания к пользовательской логике временного интеллекта.

Для начала немного изменим фильтр по году и месяцу:

DEFINE VAR YearMonthFilter = TREATAS({ 202406 }, 'Дата'[MonthKey]) EVALUATE SUMMARIZECOLUMNS('Дата'[Date] , YearMonthFilter )

Результат этого запроса такой же, как и в начале статьи.

На этот раз я установил фильтр с числовым значением в столбце [MonthKey].

Как мне вернуться к предыдущему году?

Если подумать математически, то это просто вычитание 100:

202406 – 100 = 202306

Давайте попробуем:

81fa3ca19800258dce2bfb80eb138bfd

То же самое можно сделать и с другими числовыми форматами.

Если взять, например, такой финансовый год: 2425 (для финансового года 24/25)

Вы можете вычесть 101, чтобы получить номер предыдущего финансового года: 2425 – 101 = 2324.

Другим примером пользовательской логики анализа времени является скользящее среднее значение, где для каждого дня мы вычисляем среднее значение за последние 10 дней:

3366dd7b2ce49a8cb952fdb999fa83d3

Поскольку содержимое переменной DateRange снова представляет собой список дат, я могу применить к нему функцию SAMEPERIODLASTYEAR() и получить нужный мне результат:

DEFINE VAR YearFilter = TREATAS({ 2024 }, 'Дата'[Год]) VAR MonthFilter = TREATAS({ 6 }, 'Дата'[Месяц]) // 1. Получить первую и последнюю дату для текущего контекста фильтра VAR MaxDate = CALCULATE(MAX( 'Дата'[Дата] ) ,YearFilter ,MonthFilter ) VAR MinDate = CALCULATE( DATEADD( 'Дата'[Дата], — 10, ДЕНЬ ) ,'Дата'[Дата] = MaxDate ) // 2. Сгенерировать диапазон дат, необходимый для скользящего среднего (четыре месяца) VAR DateRange = CALCULATETABLE( DATESBETWEEN( 'Дата'[Дата] ,MinDate ,MaxDate ) ) EVALUATE ТОТ ЖЕПЕРИОДЛАСТГОД( Диапазон дат )

И вот результат:

1bde57b14c67c6d5730d8b26dae63239

Эта логика возвращает 11 строк, поскольку включает последний день месяца. В зависимости от требуемого результата нам необходимо скорректировать способ вычисления первой и последней дат в списке дат (фильтр, применяемый к показателю).

Конечно, это повторение того, что я показал выше. Однако это показывает, что тот же подход можно применять к различным сценариям.

Как только вы это поймете, ваша работа с функциями временной аналитики и другими функциями, принимающими в качестве входных данных таблицы значений, станет намного проще для понимания и освоения.

Заключение

Хотя для запросов я использовал DAX Studio, вы можете использовать те же запросы в инструменте запросов DAX в Power BI Desktop.

Я намеренно использовал эти запросы, чтобы продемонстрировать, что в DAX мы постоянно работаем с таблицами, даже если не всегда осознаем это.

Но это важная деталь, которая помогает нам в понимании DAX.

Хотя часть представленного здесь кода DAX может устареть с появлением новой функции анализа времени на основе календаря в Power BI, изложенные здесь принципы остаются актуальными. Такие функции, как DATESYTD() или SAMEPERIODLASTYEAR(), по-прежнему существуют и работают так же, как и раньше. В настоящее время в этом отношении ничего не изменится, поскольку описанные здесь концепции по-прежнему актуальны.

Ссылки

Как и в предыдущих статьях, я использую пример набора данных Contoso. Вы можете бесплатно скачать набор данных ContosoRetailDW с сайта Microsoft здесь.

Данные Contoso можно свободно использовать по лицензии MIT, как описано в этом документе. Я изменил набор данных, чтобы сместить данные на современные даты.

Источник: towardsdatascience.com

Каталог бесплатных опенсорс-решений, которые можно развернуть локально и забыть о подписках

галерея

Компания Anthropic получила от Amazon 5 миллиардов долларов и в обмен пообещала инвестировать 100 миллиардов долларов в облачные сервисы.
dummy-img
Загрузка: обход банковских систем кибермошенниками и проблемы с удалением углерода.
Загрузка: обход банковских систем кибермошенниками и проблемы с удалением углерода.
dummy-img
dummy-img
Взаимодействие человека и машины погружается под воду.
Взаимодействие человека и машины погружается под воду.
Дифференциально приватное машинное обучение в масштабе с использованием JAX-Privacy
Image Not Found
Компания Anthropic получила от Amazon 5 миллиардов долларов и в обмен пообещала инвестировать 100 миллиардов долларов в облачные сервисы.

Компания Anthropic получила от Amazon 5 миллиардов долларов и в обмен пообещала инвестировать 100 миллиардов долларов в облачные сервисы.

Вкратце Опубликовано: Изображение предоставлено: Thos Robinson/Getty Images для The New York Times (откроется в новом окне) Джули Борт Компания Anthropic получила от Amazon 5 миллиардов долларов и в обмен пообещала инвестировать 100 миллиардов долларов в облачные сервисы.…

Апр 21, 2026
dummy-img

Как почистить виниловые пластинки (2026): пылесос, ультразвук, чистящий раствор, щетка.

Эти щелчки и треск недопустимы. Приведите свою музыку в порядок с помощью этого удобного руководства. Источник: www.wired.com

Апр 21, 2026
Загрузка: обход банковских систем кибермошенниками и проблемы с удалением углерода.

Загрузка: обход банковских систем кибермошенниками и проблемы с удалением углерода.

Это сегодняшний выпуск The Download, нашей ежедневной новостной рассылки, которая предоставляет вам ежедневную порцию событий в мире технологий. Кибермошенники обходят системы безопасности банков с помощью незаконных инструментов, продаваемых в Telegram. В центре по отмыванию денег в Камбодже…

Апр 21, 2026
Загрузка: обход банковских систем кибермошенниками и проблемы с удалением углерода.

Загрузка: обход банковских систем кибермошенниками и проблемы с удалением углерода.

Это сегодняшний выпуск The Download, нашей ежедневной новостной рассылки, которая предоставляет вам ежедневную порцию событий в мире технологий. Кибермошенники обходят системы безопасности банков с помощью незаконных инструментов, продаваемых в Telegram. В центре по отмыванию денег в Камбодже…

Апр 21, 2026

Впишите свой почтовый адрес и мы будем присылать вам на почту самые свежие новости в числе самых первых