В этой статье мы разберём один из ключевых инструментов в арсенале современного аналитика — язык DAX. Если вы работаете с Excel, Power BI, Tableau или любыми инструментами бизнес-аналитики, понимание DAX изменит ваше представление о возможностях анализа данных.
Что такое DAX и почему он так важен
DAX (Data Analysis Expressions) — это целая философия аналитики. Если SQL — это ваша связь с базой данных, то DAX — ваш инструмент для создания смысла из этих данных прямо в момент их визуализации. Если SQL отвечает на вопрос «какие данные у нас есть?», то DAX — «что эти данные означают для бизнеса?».
Простейшая аналогия: DAX для Power BI — это как VBA для Excel, только в тысячу раз мощнее и элегантнее.
Фундаментальные отличия DAX от SQL
Перед тем как погружаться в синтаксис, нужно понять парадигмальное различие:
- Контекст вычислений — ключевая концепция DAX;
- Ленивые вычисления — формулы вычисляются только когда нужны;
- Работа с таблицами как с сущностями — в DAX всё считается таблицами.
Пример для понимания разницы. В SQL мы пишем:
SELECT
department,
SUM(sales_amount) as total_sales
FROM sales
WHERE year = 2024
GROUP BY department;
В DAX мы создаем меру:
Total Sales 2024 =
CALCULATE(
SUM(sales[sales_amount]),
sales[year] = 2024
)
И эта мера автоматически работает в любом контексте: по отделам, по менеджерам, по месяцам — без переписывания формулы!
Основные элементы DAX
Меры (Measures) — сердце DAX
Меры — это динамические вычисления, которые работают в контексте текущего отчёта. Например, простая мера выручки:
Total Revenue = SUM(sales[amount])
Мера с условием:
Revenue This Year =
CALCULATE(
[Total Revenue],
sales[date] >= DATE(YEAR(TODAY()), 1, 1)
)
Данная мера ссылается на предыдущую и читается как: «Посчитай сумму выручки с начала текущего года».
Вычисляемые столбцы (Calculated Columns)
Столбцы добавляются в таблицу и вычисляются один раз при обновлении данных. Например, столбец с категорией клиента:
Customer Category =
IF(sales[total_purchases] > 10000, "VIP",
IF(sales[total_purchases] > 5000, "Loyal", "Standard"))
Очень похоже на формулу в Excel, не так ли? DAX — это как следующая ступень эволюции формул.
Таблицы (Tables) — продвинутый уровень
Да, в DAX можно создавать целые таблицы! Например, таблица с календарём:
Calendar =
ADDCOLUMNS(
CALENDAR(DATE(2020,1,1), DATE(2030,12,31)),
"Year", YEAR([Date]),
"Month", FORMAT([Date], "MMMM"),
"Quarter", "Q" & QUARTER([Date])
)
Контекст вычислений — магия DAX
Это самая сложная, но и самая мощная концепция. Есть два типа контекста:
- Контекст строки (Row Context) — DAX понимает, в какой строке таблицы находится;
- Контекст фильтра (Filter Context) — DAX понимает, какие фильтры применены к данным.
Практический пример. У нас есть таблица продаж, и мы создаём меру:
Average Sale Amount = AVERAGE(sales[amount])
Когда мы помещаем эту меру в визуал (например, на дашборд в Power BI), то эта мера работает динамически:
- Без фильтров — она выводит среднее по всем продажам;
- С фильтром по региону — среднее по региону;
- В таблице по менеджерам — среднее для каждого менеджера.
И нам не нужно писать отдельные формулы для каждого случая!
Ключевые функции DAX для аналитика
Думаю, теперь стало понятно, почему DAX является мощным элементом в руках аналитика. Поэтому пора перейти от общего к частному и изучить ключевые функции.
SUM,AVERAGE— это классические агрегирующие функции для подсчёта суммы и среднего значения:
Total Revenue = SUM(sales[amount])
DIVIDE— функция деления. Используется для подсчета конверсий, CTR, CR и прочего:
Share = DIVIDE(SUM(sales[clicks]), SUM(sales[Impressions]))
CALCULATE— самая важная функция, которая используется в 90% мер. Она меняет контекст вычислений:
Revenue in Europe =
CALCULATE(
[Total Revenue],
sales[region] = "Europe",
sales[status] = "Completed"
)
FILTER — фильтрация таблиц:
High Value Customers =
CALCULATE(
DISTINCTCOUNT(sales[customer_id]),
FILTER(
sales,
sales[amount] > 5000
)
)
Как вы уже заметили, в примере ранее мы тоже использовали фильтр sales[region] = "Europe", но без слова «фильтр». На самом деле, писать FILTER не обязательно, но это улучшает читабельность и позволяет писать более сложные меры — например, которые требуют сложное условие, или для Х-функций.
RELATED— работа со связанными таблицами:
Customer City = RELATED(customers[city])
Например, в нашей таблице есть только ID города, а мы хотели бы добавить наименование города в виде вычисляемого столбца. В данном случае RELATED для каждой строки находит значение в связанной таблице и возвращает его нам.
TIME INTELLIGENCE-функции. Например, скользящее среднее за 3 месяца:
Moving Average 3M =
AVERAGEX(
DATESINPERIOD(
calendar[date],
LASTDATE(calendar[date]),
-3,
MONTH
),
[Total Revenue]
)
Данная мера динамически вычисляет среднее значение выручки за последние три месяца.
Реальный бизнес-кейс: анализ воронки продаж
Давайте создадим полноценную аналитическую модель для отдела продаж.
Шаг 1. Базовые меры:
Total Leads = COUNT(leads)
Total Opportunities = COUNT(opportunities)
Total Customers = COUNT(customers)
Total Revenue = SUM(sales[amount])
Шаг 2. Меры конверсии:
Conversion Rate Lead to Opp = DIVIDE([Total Opportunities], [Total Leads], 0)
Conversion Rate Opp to Customer = DIVIDE([Total Customers], [Total Opportunities], 0)
Overall Conversion Rate = DIVIDE([Total Customers], [Total Leads], 0)
Шаг 3. Динамические показатели:
Revenue per Customer = DIVIDE([Total Revenue], [Total Customers], 0)
Sales Velocity =
DIVIDE(
[Total Revenue],
DATEDIFF(
MIN(sales[date]),
MAX(sales[date]),
DAY
)
)
Шаг 4. Анализ трендов:
Revenue YoY Growth =
VAR CurrentYear = [Total Revenue]
VAR PreviousYear =
CALCULATE(
[Total Revenue],
SAMEPERIODLASTYEAR(calendar[date])
)
RETURN
DIVIDE(CurrentYear - PreviousYear, PreviousYear, 0)
Обратите внимание: в мере Revenue YoY Growth мы использовали две переменные, которые определили через VAR, а затем возвратили через RETURN, и далее использовали в DIVIDE.
DAX vs SQL: когда что использовать?
Используйте DAX, когда нужны:
- Динамическая аналитика — меры, которые адаптируются к фильтрам;
- Работа с иерархиями — даты, категории, регионы;
- Сложные бизнес-метрики — KPI, проценты, отношения;
- Визуализация в реальном времени — интерактивные отчёты.
Используйте SQL, когда нужны:
- ETL-процессы — подготовка и трансформация данных;
- Большие объёмы данных — агрегация на уровне базы;
- Сложные соединения — когда нужен полный контроль над JOIN;
- Пакетную обработку — регулярные отчёты.
Лучшие практики работы с DAX
Для того чтобы ваша отчётность была понятна не только для других, но и для вас, придерживайтесь простых правил «чистописания»:
Именование мер
Читающий наименование меры должен чётко понимать из названия, что именно считает данная мера/столбец/таблица.
Плохо:
Measure1 = SUM(table[column])
Хорошо:
Total Revenue YTD = TOTALYTD(SUM(sales[amount]), calendar[date])
Оптимизация производительности
Х-функции (SUMX, AVERAGEX и другие) — это аналог оконной функции в мире DAX, используйте их с умом.
Медленно (вычисляется для каждой строки):
Slow Measure =
SUMX(
sales,
sales[quantity] * sales[price]
)
Быстро (агрегация один раз):
Fast Measure = SUM(sales[total_amount]) -- pre-calculated column
Комментирование сложной логики
Customer Lifetime Value =
/*
CLTV рассчитывается как:
(Средний чек) × (Частота покупок) × (Время жизни клиента)
*/
VAR AvgPurchase = [Average Purchase Amount]
VAR PurchaseFreq = [Purchase Frequency]
VAR CustomerLife = [Average Customer Lifespan]
RETURN
AvgPurchase * PurchaseFreq * CustomerLife
Применение этих трёх базовых принципов значительно упростит вашу работу.
Типичные ошибки новичков
Ошибка 1: путаница мер и столбцов
Неправильно (столбец вместо меры):
Sales Amount = sales[amount] * sales[quantity]
Правильно (мера):
Sales Amount = SUMX(sales, sales[amount] * sales[quantity])
Ошибка 2: игнорирование контекста
Неправильно:
Total All Regions = SUM(sales[amount])
Будет показывать сумму только для фильтрованного региона.
Правильно:
Total All Regions =
CALCULATE(
SUM(sales[amount]),
ALL(sales[region])
)
Будет показывать общую сумму, так как благодаря функции ALL мы отключаем фильтр региона и мера не будет пересчитываться при использовании данного фильтра.
Интеграция DAX и SQL
В реальных проектах, например в построении отчётности, мы часто комбинируем оба инструмента. Например, SQL подготавливает данные на уровне базы:
SELECT
customer_id,
COUNT(order_id) as order_count,
SUM(amount) as lifetime_value
FROM orders
GROUP BY customer_id;
DAX уже делает динамический анализ в Power BI:
Customer Segment =
SWITCH(
TRUE(),
[Lifetime Value] > 10000, "VIP",
[Order Count] > 10, "Loyal",
"Regular"
)
Как начать изучать DAX эффективно
- Начните с простых агрегаций — SUM, COUNT, AVERAGE;
- Освойте CALCULATE — это 90% мощности DAX;
- Практикуйтесь на реальных данных — создайте свой первый дашборд;
- Изучайте Time Intelligence — анализ временных рядов;
- Читайте DAX Formatter — учитесь у профессионалов.
DAX — это мышление аналитика, воплощённое в коде. Он позволяет:
- Создавать интеллектуальные метрики, которые понимают контекст;
- Строить сложные аналитические модели без программирования;
- Делать интерактивную аналитику доступной для бизнес-пользователей.
Самый важный совет: не пытайтесь выучить все функции DAX сразу. Начните с 5-10 ключевых функций, поймите концепцию контекста, и вы уже сможете решать 90% бизнес-задач.
Помните: хороший аналитик знает SQL, а великий — и SQL, и DAX. Это сочетание позволяет вам не только добывать данные, но и превращать их в реальные бизнес-инсайты.
