DAX: подробный гайд по созданию таблиц для бизнес-аналитики

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Для кого эта статья:

  • начинающие и продвинутые бизнес-аналитики
  • специалисты, изучающие Power BI и DAX
  • профессионалы, желающие улучшить навыки анализа данных и оптимизации моделей

Точность аналитики прямо пропорциональна качеству ваших данных и инструментов их обработки. DAX (Data Analysis Expressions) — возможно, самый мощный и недооценённый инструмент в арсенале бизнес-аналитика, работающего с Power BI. Если вы до сих пор используете базовые техники и не погрузились в создание продвинутых таблиц с помощью DAX, вы буквально оставляете ценные бизнес-инсайты лежать на поверхности, не способные превратить их в конкурентное преимущество. 📊 Пришло время это изменить.

Осваиваете Power BI и хотите стать профессиональным BI-аналитиком, чтобы создавать бизнес-аналитику на уровне экспертов? Курс «BI-аналитик» с нуля от Skypro погрузит вас в мир формул DAX и построения сложных моделей данных. Всего за 6 месяцев вы пройдете путь от знакомства с базовыми понятиями до создания интерактивных дашбордов, которые трансформируют ваш подход к аналитике данных.

DAX для начинающих: основы создания таблиц в Power BI

Язык DAX — это то, что отличает професcиональную бизнес-аналитику от любительской "игры с графиками". Создание таблиц с помощью DAX в Power BI позволяет выстраивать не просто визуализацию данных, а полноценную аналитическую платформу.

Начнём с базового понимания. DAX-таблицы существуют в двух формах:

  • Вычисляемые таблицы — создаются с помощью формулы и хранятся в памяти модели данных
  • Таблицы мер — специальные таблицы для группировки и организации мер

Для создания вычисляемой таблицы в Power BI выполните следующие шаги:

  1. В представлении "Модель" нажмите на вкладку "Моделирование"
  2. Выберите "Новая таблица"
  3. В строке формул введите выражение, начинающееся с названия таблицы

Простейший пример создания новой таблицы выглядит так:

Календарь = CALENDAR(DATE(2020,1,1), DATE(2025,12,31))

Эта формула создаст таблицу дат с 1 января 2020 по 31 декабря 2025 года — идеальное начало для временного анализа. 📆

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

Тип таблицыПреимуществаОграничения
ИмпортированныеНе требуют вычислений, быстрая загрузкаНужно внешнее обновление источника
Вычисляемые (DAX)Динамическое создание, гибкостьПотребление ресурсов, сложность отладки
Таблицы мерОрганизация и группировка мерНет хранения данных, только меры

Анна Вершинина, BI-руководитель проектов

Когда я начинала работать с Power BI в финтех-компании, главной проблемой был анализ сезонности транзакций. Данные приходили из различных систем без единой структуры дат. Решение пришло, когда я создала единую таблицу календаря через DAX:

Календарь = 
VAR МинДата = MIN(Транзакции[Дата])
VAR МаксДата = MAX(Транзакции[Дата])
RETURN
ADDCOLUMNS(
CALENDAR(МинДата, МаксДата),
"Год", YEAR([Date]),
"Квартал", QUARTER([Date]),
"Месяц", MONTH([Date]),
"Неделя года", WEEKNUM([Date]),
"День недели", WEEKDAY([Date]),
"Выходной", IF(WEEKDAY([Date])>5, "Да", "Нет")
)

Эта таблица полностью трансформировала нашу аналитику. Мы не только получили стандартизированную структуру для разных источников, но и смогли выявить важные паттерны в поведении клиентов. Например, обнаружили 27% рост транзакций в пятницу вечером перед праздничными выходными — именно это знание позволило оптимизировать маркетинговые кампании и увеличить конверсию на 18%.

Для начинающих критически важно понимать, что DAX-таблицы — это не просто альтернатива импорту данных. Это способ расширить логику модели данных, создавая связи и измерения, которых не было в исходных данных.

Кинга Идем в IT: пошаговый план для смены профессии

Синтаксис DAX при разработке таблиц: от простого к сложному

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

Базовый синтаксис создания таблицы в DAX выглядит следующим образом:

ИмяТаблицы = ФОРМУЛА()

Существует несколько ключевых функций для создания таблиц:

  • FILTER() — фильтрует существующую таблицу по заданным условиям
  • CALCULATETABLE() — вычисляет таблицу в контексте указанных фильтров
  • ADDCOLUMNS() — добавляет вычисляемые столбцы в таблицу
  • SUMMARIZE() — группирует данные и создает итоги
  • UNION(), INTERSECT(), EXCEPT() — операции над множествами таблиц

Рассмотрим использование этих функций в порядке возрастания сложности. 🚀

Фильтрация таблицы — самая базовая операция:

АктивныеКлиенты = 
FILTER(
Клиенты,
Клиенты[СтатусАктивности] = "Активен"
)

Сложнее становится, когда необходимо применить несколько фильтров или условий:

ВыгодныеКлиенты = 
FILTER(
Клиенты,
Клиенты[СреднийЧек] > 5000
&& RELATED(Регионы[Название]) = "Москва"
)

Для продвинутых сценариев используйте комбинации функций. Например, создание агрегированной таблицы:

ПродажиПоКатегориям = 
SUMMARIZE(
Продажи,
Продукты[Категория],
"ОбщаяСумма", SUM(Продажи[Сумма]),
"КоличествоТранзакций", COUNTROWS(Продажи)
)

Существенное усложнение происходит при работе с табличными выражениями, особенно когда требуется контекстная модификация:

СравнениеПериодов = 
ADDCOLUMNS(
VALUES(Даты[Месяц]),
"ТекущиеПродажи", CALCULATE(SUM(Продажи[Сумма]), Даты[Год] = 2025),
"ПрошлыеПродажи", CALCULATE(SUM(Продажи[Сумма]), Даты[Год] = 2024),
"ИзменениеПроцент", 
VAR Текущие = CALCULATE(SUM(Продажи[Сумма]), Даты[Год] = 2025)
VAR Прошлые = CALCULATE(SUM(Продажи[Сумма]), Даты[Год] = 2024)
RETURN DIVIDE(Текущие – Прошлые, Прошлые, 0)
)

В DAX критически важно понимание контекста вычислений. Если в SQL вы работаете с декларативными запросами, то в DAX — с контекстной моделью вычислений, где значение выражения может меняться в зависимости от контекста строки и фильтра.

Функция DAXАналог в SQLОсобенности в DAX
FILTER()WHEREВозвращает таблицу, не просто условие
SUMMARIZE()GROUP BYПозволяет добавлять выражения прямо в функцию
ADDCOLUMNS()SELECT с вычислениямиПоддерживает переменные и сложную логику
CALCULATETABLE()Нет прямого аналогаИзменяет контекст фильтра для вычисления

Техники создания вычисляемых таблиц в DAX для аналитики

Использование DAX для создания вычисляемых таблиц открывает поистине революционные возможности для аналитики, недоступные в традиционных BI-инструментах. Освоив эти техники, вы сможете создавать сложные аналитические модели без необходимости предварительной подготовки данных в ETL-процессах. 💼

Ключевые техники создания вычисляемых таблиц, которые должен освоить каждый продвинутый аналитик:

  1. Создание справочных таблиц данных — календари, бюджетные периоды, организационные структуры
  2. Объединение данных из разных источников — консолидация сходных таблиц
  3. Преобразование структуры данных — разворачивание/сворачивание (pivoting)
  4. Создание рангов и сегментаций — классификация клиентов, ABC-анализ
  5. Темпоральные преобразования — создание скользящих периодов, сравнительный анализ

Рассмотрим несколько практических примеров:

1. Создание динамической справочной таблицы для ABC-анализа клиентов:

КлассификацияКлиентов = 
VAR СуммыПродаж = 
SUMMARIZE(
Продажи,
Клиенты[КлиентID],
"Продажи", SUM(Продажи[Сумма])
)
VAR ОбщаяСумма = SUMX(СуммыПродаж, [Продажи])
VAR РанжированныеКлиенты = 
ADDCOLUMNS(
СуммыПродаж,
"ДоляПродаж", DIVIDE([Продажи], ОбщаяСумма),
"НакопительнаяДоля", 
CALCULATE(
SUMX(СуммыПродаж, [Продажи])/ОбщаяСумма,
FILTER(
СуммыПродаж,
[Продажи] >= EARLIER([Продажи])
)
)
)
RETURN
ADDCOLUMNS(
РанжированныеКлиенты,
"Категория", 
IF([НакопительнаяДоля] <= 0.8, "A",
IF([НакопительнаяДоля] <= 0.95, "B", "C"))
)

2. Создание таблицы сравнения с предыдущим периодом:

СравнениеПериодов = 
VAR Периоды = VALUES(Календарь[Месяц])
RETURN
ADDCOLUMNS(
Периоды,
"ТекущийПериод", SUM(Продажи[Сумма]),
"ПредыдущийПериод", 
CALCULATE(
SUM(Продажи[Сумма]),
DATEADD(Календарь[Дата], -1, MONTH)
),
"Изменение", [ТекущийПериод] – [ПредыдущийПериод],
"ИзменениеПроцент", 
DIVIDE(
[ТекущийПериод] – [ПредыдущийПериод],
[ПредыдущийПериод],
0
)
)

Максим Соколов, Lead BI Developer

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

Традиционный подход требовал создания огромного количества срезов и перекрестных фильтров, что делало работу с отчетом крайне неудобной. Решение пришло в виде сложной вычисляемой таблицы:

АнализСпроса = 
VAR БазовыеДанные = 
SUMMARIZE(
Продажи,
'Продукт'[Категория], 
'Магазин'[Регион], 
'Дата'[Месяц], 
"Продажи", SUM(Продажи[Количество]),
"Доход", SUM(Продажи[Сумма])
)
VAR СопоставлениеАкций = 
GENERATE(
БазовыеДанные,
CALCULATETABLE(
ADDCOLUMNS(
VALUES('Маркетинг'[Кампания]),
"АктивнаВПериод", 
OR(
'Дата'[Месяц] = 'Маркетинг'[НачалоМесяц],
'Дата'[Месяц] = 'Маркетинг'[КонецМесяц]
)
),
FILTER(ALL('Маркетинг'), 
'Маркетинг'[Регион] = EARLIER('Магазин'[Регион]) &&
'Маркетинг'[Категория] = EARLIER('Продукт'[Категория])
)
)
)
RETURN 
FILTER(СопоставлениеАкций, [АктивнаВПериод] = TRUE())

Эта таблица позволила сопоставить данные о продажах с периодами маркетинговых активностей автоматически. После внедрения время на анализ эффективности акций сократилось с двух дней до 20 минут, а точность прогнозов выросла на 34%. Особенно ценной находкой оказалась возможность моделировать "что если" сценарии для будущих маркетинговых кампаний, что в итоге привело к 7.8% увеличению оборота.

Сомневаетесь в выборе карьерного пути в аналитике? Не уверены, подходит ли вам именно работа с DAX и Power BI? Пройдите Тест на профориентацию от Skypro и получите персональную карту ваших сильных сторон в аналитике данных. Всего 3 минуты — и вы узнаете, в каком направлении лучше развиваться: от бизнес-аналитики до Data Science, и какие навыки стоит освоить именно вам.

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

МатрицаПродуктыКлиенты = 
GENERATE(
VALUES(Клиенты[Имя]),
CALCULATETABLE(
SUMMARIZE(
Продукты,
Продукты[Категория],
"Сумма", SUM(Продажи[Сумма])
),
ALLEXCEPT(Продажи, Продажи[КлиентID])
)
)

Для особо сложных случаев рекомендуется использовать подход с временными переменными, которые помогают разбить расчет на логические шаги и упростить отладку:

СложныйАнализ = 
VAR Шаг1 = SUMMARIZE(...) // Первый этап расчета
VAR Шаг2 = FILTER(Шаг1, ...) // Второй этап
VAR Шаг3 = ADDCOLUMNS(Шаг2, ...) // Третий этап
RETURN Шаг3

Оптимизация производительности таблиц DAX в крупных проектах

По мере роста сложности аналитических моделей производительность DAX-таблиц становится критическим фактором успеха проекта. Неоптимизированные вычисляемые таблицы могут превратить многообещающий дашборд в неработоспособное решение. ⚠️

Основные принципы оптимизации производительности:

  1. Минимизация объема данных — фильтруйте данные на самом раннем этапе
  2. Эффективное использование контекста — правильно применяйте CALCULATE и CALCULATETABLE
  3. Кэширование промежуточных результатов — используйте переменные VAR
  4. Избегайте излишних операций — не используйте FILTER там, где достаточно фильтров CALCULATE
  5. Оптимизируйте модель данных — правильные связи важнее сложных формул

Рассмотрим пример оптимизации типичной вычисляемой таблицы:

Неоптимальный вариант:

// Плохая производительность
СводнаяТаблица = 
FILTER(
ADDCOLUMNS(
CROSSJOIN(
VALUES(Продукты[Категория]),
VALUES(Даты[Месяц])
),
"Продажи", CALCULATE(SUM(Продажи[Сумма]))
),
[Продажи] > 0
)

Оптимизированный вариант:

// Хорошая производительность
СводнаяТаблица = 
VAR БазовыеДанные = 
SUMMARIZE(
Продажи,
Продукты[Категория],
Даты[Месяц],
"Продажи", SUM(Продажи[Сумма])
)
RETURN
FILTER(БазовыеДанные, [Продажи] > 0)

Особенно важно оптимизировать использование функций с высокими ресурсными затратами. К ним относятся:

  • CROSSJOIN — создаёт декартово произведение, опасно при больших наборах
  • EARLIER — многократное использование может экспоненциально замедлить расчеты
  • FILTER — требует перебора всех строк, не использует индексы
  • RANKX — ресурсоемкая функция при больших таблицах

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

  1. VertiPaq Analyzer — для анализа структуры модели
  2. DAX Studio — для профилирования запросов
  3. Performance Analyzer в Power BI — для выявления "узких мест"

При работе с крупными проектами особое внимание уделяйте инкрементальному обновлению данных. Вычисляемые таблицы должны быть спроектированы с учетом этого требования:

ОптимизированнаяТаблица = 
VAR ПоследнееОбновление = MAX(Метаданные[ДатаОбновления])
VAR НовыеДанные = 
FILTER(
Транзакции,
Транзакции[Дата] >= ПоследнееОбновление – 7
)
RETURN
UNION(
FILTER(СуществующиеРезультаты, 
СуществующиеРезультаты[Дата] < ПоследнееОбновление – 7),
SUMMARIZE(НовыеДанные, ...)
)

В крупных корпоративных решениях критически важным фактором становится сегментация вычисляемых таблиц — разделение больших таблиц на тематические сегменты, что позволяет ускорить расчеты для конкретных сценариев использования:

// Вместо одной большой таблицы
ФинансовыеПоказатели = 
FILTER(
SUMMARIZE(...очень сложный расчет...),
[Регион] IN {"Москва", "Санкт-Петербург", ...}
)

// Создайте отдельные таблицы
ФинансыМосква = 
CALCULATE(
SUMMARIZE(...тот же расчет, но оптимизированный...),
Регионы[Название] = "Москва"
)

ФинансыСПб = 
CALCULATE(
SUMMARIZE(...тот же расчет, но оптимизированный...),
Регионы[Название] = "Санкт-Петербург"
)

Реальные бизнес-сценарии применения таблиц DAX

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

1. Прогнозирование спроса и планирование запасов

Создание вычисляемой таблицы прогноза на основе исторических данных:

ПрогнозЗапасов = 
VAR ИсторияПродаж = 
SUMMARIZE(
Продажи,
'Продукт'[SKU],
'Дата'[Месяц],
"КоличествоПродано", SUM(Продажи[Количество])
)
VAR СреднееПотребление = 
AVERAGEX(
FILTER(
ИсторияПродаж,
'Дата'[Год] = 2024 &&
'Дата'[Месяц] <= MONTH(TODAY())
),
[КоличествоПродано]
)
VAR ТекущиеЗапасы = 
SUMMARIZE(
Склад,
'Продукт'[SKU],
"ТекущийЗапас", SUM(Склад[Количество])
)
RETURN
ADDCOLUMNS(
ТекущиеЗапасы,
"ПрогнозДнейОбеспеченности", 
DIVIDE([ТекущийЗапас], DIVIDE([КоличествоПродано], 30), 0),
"СтатусЗапаса",
IF([ПрогнозДнейОбеспеченности] < 7, "Критический",
IF([ПрогнозДнейОбеспеченности] < 14, "Низкий",
IF([ПрогнозДнейОбеспеченности] > 90, "Избыточный", "Нормальный")))
)

2. Анализ клиентской лояльности и сегментация

Сегментация клиентов по показателям RFM (Recency, Frequency, Monetary):

RFMАнализ = 
VAR РасчетR = 
ADDCOLUMNS(
VALUES(Клиенты[КлиентID]),
"Recency", DATEDIFF(MAX(Заказы[Дата]), TODAY(), DAY),
"RScore", 
IF(
DATEDIFF(MAX(Заказы[Дата]), TODAY(), DAY) <= 30, 3,
IF(DATEDIFF(MAX(Заказы[Дата]), TODAY(), DAY) <= 90, 2, 1)
)
)
VAR РасчетF = 
ADDCOLUMNS(
РасчетR,
"Frequency", COUNTROWS(Заказы),
"FScore", 
IF(
COUNTROWS(Заказы) >= 10, 3,
IF(COUNTROWS(Заказы) >= 5, 2, 1)
)
)
VAR РасчетM = 
ADDCOLUMNS(
РасчетF,
"Monetary", SUM(Заказы[Сумма]),
"MScore", 
IF(
SUM(Заказы[Сумма]) >= 100000, 3,
IF(SUM(Заказы[Сумма]) >= 50000, 2, 1)
)
)
RETURN
ADDCOLUMNS(
РасчетM,
"RFMScore", [RScore] & [FScore] & [MScore],
"Сегмент", 
SWITCH(
TRUE(),
[RFMScore] = "333", "VIP",
[RFMScore] IN {"332", "323", "233"}, "Лояльные",
[RFMScore] IN {"331", "313", "133"}, "Перспективные",
[RFMScore] IN {"111", "112", "121"}, "Спящие",
"Стандартные"
)
)

3. Продвинутый финансовый анализ

Динамическое построение P&L (Profit & Loss) отчета:

ФинансовыйАнализ = 
VAR ДоходыРасходы = 
UNION(
SUMMARIZE(
Доходы,
'Период'[Месяц],
"Категория", "Доход",
"Сумма", SUM(Доходы[Сумма])
),
SUMMARIZE(
Расходы,
'Период'[Месяц],
"Категория", "Расход",
"Сумма", SUM(Расходы[Сумма]) * -1
)
)
VAR ВаловаяПрибыль = 
ADDCOLUMNS(
VALUES('Период'[Месяц]),
"Категория", "Валовая прибыль",
"Сумма", 
CALCULATE(
SUM(ДоходыРасходы[Сумма])
)
)
VAR МаржаПрибыли = 
ADDCOLUMNS(
ВаловаяПрибыль,
"Категория", "Маржа (%)",
"Сумма", 
DIVIDE(
CALCULATE(
SUM(ДоходыРасходы[Сумма]),
),
CALCULATE(
SUM(ДоходыРасходы[Сумма]),
ДоходыРасходы[Категория] = "Доход"
),
0
) * 100
)
RETURN
UNION(ДоходыРасходы, ВаловаяПрибыль, МаржаПрибыли)

4. Мониторинг ключевых показателей эффективности (KPI) и отклонений

Таблица с автоматическим выявлением отклонений от плановых показателей:

МониторингKPI = 
ADDCOLUMNS(
NATURALINNERJOIN(
VALUES(KPI[Показатель]),
SUMMARIZE(
Факты,
'Период'[Год],
'Период'[Месяц],
"ФактЗначение", SUM(Факты[Значение])
)
),
"ПланЗначение", CALCULATE(SUM(План[Значение])),
"Выполнение", DIVIDE([ФактЗначение], [ПланЗначение], 0),
"Отклонение", [ФактЗначение] – [ПланЗначение],
"ОтклонениеПроцент", DIVIDE([ФактЗначение] – [ПланЗначение], [ПланЗначение], 0),
"Статус", 
IF([Выполнение] >= 1, "Выполнено", 
IF([Выполнение] >= 0.9, "Риск невыполнения", "Не выполнено")),
"ТрендИзменения",
VAR ПредыдущийМесяц = 
CALCULATE(
SUM(Факты[Значение]),
DATEADD('Период'[Дата], -1, MONTH)
)
RETURN
IF([ФактЗначение] > ПредыдущийМесяц, "Рост",
IF([ФактЗначение] < ПредыдущийМесяц, "Снижение", "Стабильно"))
)

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

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