Язык DAX¶
DAX (Data Analysis Expressions) — это язык формул и выражений, разработанный компанией Microsoft для выполнения вычислений, определения мер и создания вычисляемых столбцов в моделях данных, используемых в таких продуктах, как Power BI, Analysis Services (табличный режим) и Power Pivot в Excel. DAX относится к классу функциональных языков, ориентированных на работу с реляционными данными, и по синтаксису напоминает формулы Excel, но обладает более мощными возможностями для работы с таблицами и фильтрацией контекста. Ключевая характеристика DAX — способность выполнять вычисления в динамическом контексте строки и фильтра, что отличает его от стандартных языков запросов, таких как SQL.
¶История
Разработка DAX началась в конце 2000-х годов как часть проекта Microsoft по созданию нового поколения средств бизнес-аналитики (BI), ориентированных на быстродействие и простоту использования. Первая публичная версия языка была представлена в 2010 году вместе с выпуском Power Pivot для Excel 2010 (надстройка для работы с большими объёмами данных). В 2012 году DAX был интегрирован в SQL Server Analysis Services (SSAS) в табличном режиме, что позволило использовать его в корпоративных решениях. С 2015 года, с выходом Power BI Desktop, DAX стал основным языком вычислений для этой платформы, которая быстро завоевала популярность среди аналитиков и бизнес-пользователей. В последующие годы Microsoft регулярно обновляла DAX, добавляя новые функции (например, TREATAS, GENERATE, функции для работы с датами и временными рядами), улучшая производительность и расширяя совместимость с различными источниками данных.
¶Основные концепции
¶Контекст строки и контекст фильтра
Фундаментальное понятие в DAX — контекст. Вычисления в DAX выполняются в двух типах контекста: контексте строки и контексте фильтра.
- Контекст строки — это текущая строка таблицы, обрабатываемая в итераторе (например, в функциях SUMX, FILTER, ADDCOLUMNS). Внутри контекста строки можно ссылаться на значения столбцов текущей строки.
- Контекст фильтра — это набор фильтров, применяемых к таблице или модели данных. Он может быть задан явно (через функции CALCULATE, FILTER) или неявно (через визуальные элементы отчёта, срезы, оси сводной таблицы). Контекст фильтра определяет, какие строки таблицы участвуют в вычислении.
Взаимодействие этих двух контекстов позволяет DAX выполнять сложные агрегации и динамические расчёты, которые невозможно реализовать в Excel без дополнительных надстроек.
¶Меры и вычисляемые столбцы
DAX используется для создания двух основных типов объектов: мер и вычисляемых столбцов.
- Мера — это динамическое вычисление, которое выполняется в контексте фильтра отчёта. Мера не хранится в таблице, а вычисляется при каждом обращении к ней. Например, мера «Общая выручка» может быть определена как
SUM(Sales[Amount])и будет пересчитываться в зависимости от выбранных срезов по дате, региону или продукту. - Вычисляемый столбец — это столбец, добавляемый в таблицу и вычисляемый один раз при загрузке или обновлении данных. Его значение хранится в модели и не зависит от контекста фильтра отчёта. Например, столбец «Год» может быть получен из столбца «Дата» с помощью функции
YEAR.
¶Таблицы и скалярные значения
DAX работает с двумя типами результатов: таблицами и скалярными значениями (одно число, строка, дата). Большинство функций DAX возвращают либо таблицу (например, FILTER, VALUES, ALL), либо скаляр (например, SUM, AVERAGE, COUNT). Меры всегда возвращают скалярные значения, в то время как вычисляемые столбцы могут содержать как скаляры, так и таблицы (но в виде столбца хранится только скалярный результат).
¶Классификация функций
Функции DAX делятся на несколько категорий по назначению:
¶Агрегатные функции
Используются для суммирования, усреднения, подсчёта количества строк и других статистических операций. Примеры: SUM, AVERAGE, COUNT, MIN, MAX, DISTINCTCOUNT (подсчёт уникальных значений).
¶Функции работы с таблицами
Возвращают таблицы или выполняют операции над таблицами. К ним относятся:
- Фильтрующие функции:
FILTER(возвращает строки, удовлетворяющие условию),ALL(снимает все фильтры с таблицы),ALLEXCEPT(снимает все фильтры, кроме указанных),CALCULATETABLE(изменяет контекст фильтра и возвращает таблицу). - Функции для создания таблиц:
VALUES(возвращает уникальные значения столбца),DISTINCT(аналогично, но без учёта пустых значений),GENERATE(создаёт декартово произведение),ADDCOLUMNS(добавляет вычисляемые столбцы к таблице). - Функции для работы с отношениями:
RELATED(возвращает значение из связанной таблицы),RELATEDTABLE(возвращает таблицу из связанной таблицы).
¶Функции даты и времени
Предназначены для работы с датами, временными периодами и календарями. Примеры: DATE, YEAR, MONTH, DAY, TODAY, NOW, DATEDIFF, EOMONTH. Особую группу составляют функции для работы с временными интеллектами (Time Intelligence), такие как TOTALYTD, SAMEPERIODLASTYEAR, DATEADD, DATESBETWEEN, которые позволяют сравнивать показатели за разные периоды.
¶Логические функции
Выполняют условные операции. Основные: IF, AND, OR, NOT, SWITCH (аналог множественного выбора), IFERROR.
¶Функции для работы с текстом
Позволяют манипулировать строками: CONCATENATE, LEFT, RIGHT, MID, LEN, FIND, REPLACE, UPPER, LOWER, TRIM.
¶Функции для работы с фильтрами
Используются для изменения контекста фильтра. Ключевая функция — CALCULATE, которая изменяет контекст фильтра и вычисляет выражение в новом контексте. CALCULATE является одной из самых мощных и часто используемых функций DAX, так как позволяет динамически переопределять фильтры, заданные в отчёте.
¶Функции для работы с родительско-дочерними иерархиями
Применяются для анализа данных с иерархической структурой (например, организационная структура, категории товаров). Примеры: PATH, PATHITEM, PATHLENGTH, PATHCONTAINS.
¶Примеры использования
¶Пример 1: Простая мера
``dax Total Sales = SUM(Sales[Amount]) ` Эта мера суммирует все значения столбца Amount из таблицы Sales` в текущем контексте фильтра.
¶Пример 2: Мера с изменением контекста
``dax Sales Previous Year = CALCULATE( SUM(Sales[Amount]), SAMEPERIODLASTYEAR('Calendar'[Date]) ) ` Эта мера вычисляет сумму продаж за аналогичный период предыдущего года, используя функцию SAMEPERIODLASTYEAR` для сдвига дат.
¶Пример 3: Вычисляемый столбец
``dax Profit Margin = DIVIDE( Sales[Profit], Sales[Revenue], 0 ) `` Этот столбец вычисляет маржу прибыли как отношение прибыли к выручке, с обработкой деления на ноль (возвращает 0).
¶Пример 4: Использование FILTER
``dax High Value Sales = CALCULATE( SUM(Sales[Amount]), FILTER( Sales, Sales[Amount] > 1000 ) ) `` Эта мера суммирует только те продажи, где сумма превышает 1000.
¶Применение
DAX широко используется в следующих областях:
- Бизнес-аналитика (BI): создание отчётов и дашбордов в Power BI, где DAX позволяет вычислять ключевые показатели эффективности (KPI), динамические агрегации, сравнения периодов, накопительные итоги.
- Финансовый анализ: расчёт рентабельности, маржи, оборачиваемости, прогнозирование на основе временных рядов.
- Маркетинг и продажи: анализ воронки продаж, сегментация клиентов, расчёт LTV (пожизненной ценности клиента), когортный анализ.
- Логистика и производство: расчёт запасов, оборачиваемости, времени выполнения заказов, анализ эффективности цепочек поставок.
- HR-аналитика: расчёт текучести кадров, среднего стажа, затрат на персонал.
¶Критика и ограничения
Несмотря на широкую популярность, DAX имеет ряд недостатков и ограничений:
- Сложность обучения: из-за концепции контекста и неявных преобразований типов новички часто допускают ошибки, которые трудно отлаживать.
- Производительность: неправильно написанные выражения DAX могут приводить к медленным вычислениям, особенно при работе с большими объёмами данных (миллионы строк). Оптимизация требует понимания внутреннего устройства движка VertiPaq.
- Отсутствие циклов и переменных в классическом понимании: хотя в DAX есть переменные (VAR), они не поддерживают итерации в привычном для программистов виде, что усложняет реализацию некоторых алгоритмов.
- Зависимость от модели данных: DAX тесно связан со структурой таблиц и связей в модели, и изменение схемы может потребовать переписывания всех выражений.
- Ограниченная поддержка строковых операций: по сравнению с языками общего назначения, DAX имеет меньше возможностей для работы с текстом (например, нет регулярных выражений).
¶Сравнение с другими языками
- DAX vs SQL: SQL — язык запросов, ориентированный на извлечение и манипуляцию данными в реляционных базах. DAX — язык вычислений, работающий поверх уже загруженных данных в памяти. SQL не поддерживает динамический контекст фильтра и временные интеллекты, но лучше подходит для сложных операций с множественными соединениями и подзапросами.
- DAX vs MDX (Multidimensional Expressions): MDX — язык для многомерных кубов, более сложный и менее интуитивный. DAX проще для пользователей Excel, но MDX предоставляет более мощные возможности для работы с иерархиями и многомерными агрегатами.
- DAX vs M (Power Query): M — язык для извлечения, преобразования и загрузки данных (ETL), в то время как DAX — для вычислений в уже загруженной модели. M не имеет контекста фильтра и не предназначен для создания мер.
¶Интересные факты
- DAX не является языком запросов — он не может напрямую извлекать данные из внешних источников. Для этого используется Power Query (язык M).
- Внутренний движок DAX, VertiPaq, использует сжатие данных и хранение в столбцовом формате, что обеспечивает высокую скорость вычислений для больших объёмов данных.
- Microsoft регулярно выпускает обновления DAX, добавляя новые функции. Например, в 2022 году были добавлены функции
INDEX,OFFSET,WINDOWдля работы с окнами. - DAX поддерживает рекурсию через функции итераторов, но это требует осторожного подхода из-за риска бесконечных циклов.
¶Источники
- Microsoft Learn: «Руководство по DAX» (официальная документация)
- Alberto Ferrari, Marco Russo. «The Definitive Guide to DAX» (Microsoft Press, 2019)
- Power BI Blog: «DAX update history» (блог Microsoft)
- SQLBI.com: «DAX Patterns» (коллекция шаблонов и примеров)
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →

