DAX: подробный гайд по созданию таблиц для бизнес-аналитики
Пройдите тест, узнайте какой профессии подходите
Для кого эта статья:
- начинающие и продвинутые бизнес-аналитики
- специалисты, изучающие 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 выполните следующие шаги:
- В представлении "Модель" нажмите на вкладку "Моделирование"
- Выберите "Новая таблица"
- В строке формул введите выражение, начинающееся с названия таблицы
Простейший пример создания новой таблицы выглядит так:
Календарь = 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-таблицы — это не просто альтернатива импорту данных. Это способ расширить логику модели данных, создавая связи и измерения, которых не было в исходных данных.

Синтаксис 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-процессах. 💼
Ключевые техники создания вычисляемых таблиц, которые должен освоить каждый продвинутый аналитик:
- Создание справочных таблиц данных — календари, бюджетные периоды, организационные структуры
- Объединение данных из разных источников — консолидация сходных таблиц
- Преобразование структуры данных — разворачивание/сворачивание (pivoting)
- Создание рангов и сегментаций — классификация клиентов, ABC-анализ
- Темпоральные преобразования — создание скользящих периодов, сравнительный анализ
Рассмотрим несколько практических примеров:
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-таблиц становится критическим фактором успеха проекта. Неоптимизированные вычисляемые таблицы могут превратить многообещающий дашборд в неработоспособное решение. ⚠️
Основные принципы оптимизации производительности:
- Минимизация объема данных — фильтруйте данные на самом раннем этапе
- Эффективное использование контекста — правильно применяйте CALCULATE и CALCULATETABLE
- Кэширование промежуточных результатов — используйте переменные VAR
- Избегайте излишних операций — не используйте FILTER там, где достаточно фильтров CALCULATE
- Оптимизируйте модель данных — правильные связи важнее сложных формул
Рассмотрим пример оптимизации типичной вычисляемой таблицы:
Неоптимальный вариант:
// Плохая производительность
СводнаяТаблица =
FILTER(
ADDCOLUMNS(
CROSSJOIN(
VALUES(Продукты[Категория]),
VALUES(Даты[Месяц])
),
"Продажи", CALCULATE(SUM(Продажи[Сумма]))
),
[Продажи] > 0
)
Оптимизированный вариант:
// Хорошая производительность
СводнаяТаблица =
VAR БазовыеДанные =
SUMMARIZE(
Продажи,
Продукты[Категория],
Даты[Месяц],
"Продажи", SUM(Продажи[Сумма])
)
RETURN
FILTER(БазовыеДанные, [Продажи] > 0)
Особенно важно оптимизировать использование функций с высокими ресурсными затратами. К ним относятся:
- CROSSJOIN — создаёт декартово произведение, опасно при больших наборах
- EARLIER — многократное использование может экспоненциально замедлить расчеты
- FILTER — требует перебора всех строк, не использует индексы
- RANKX — ресурсоемкая функция при больших таблицах
Для эффективной оптимизации используйте средства мониторинга и диагностики:
- VertiPaq Analyzer — для анализа структуры модели
- DAX Studio — для профилирования запросов
- 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 сегодня, чтобы завтра ваша аналитика работала на опережение конкурентов.