Аналитика15 октября 2026 г.

Гранулярность таблицы фактов: как проверить модель Power BI до построения отчета

#COURSE##INNER#

Гранулярность таблицы фактов: как проверить модель Power BI до построения отчета

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

Короткий ориентир такой: сначала запишите бизнес-смысл одной строки в каждой таблице, потом проверьте уникальность ключей на стороне one, а после этого сверяйте итоги на двух-трех реальных или учебных заказах. Если на этом шаге сумма «на строках» не совпадает с суммой «по заказам», проблема не в визуализации, а в смешении уровней детализации.

Одна строка и ее бизнес-смысл

Гранулярность, или зерно таблицы, удобнее проверять не по названию таблицы, а одной фразой. Для таблицы SalesLines правильная фраза может звучать так: «одна строка — одна товарная позиция в одном заказе». Для таблицы Orders другая: «одна строка — один заказ целиком». Эти две фразы похожи, но для модели они означают разный уровень учета.

Из-за этого ошибка часто возникает еще до расчётов. Аналитик видит в таблице Orders поле OrderAmount и считает, что его можно свободно использовать рядом с товарами из таблицы строк заказа. Но сумма заказа относится ко всему заказу, а не к отдельной позиции. Если один заказ содержит две строки, то его шапочный итог нельзя без проверки переносить в контекст строк или товаров: он либо будет повторяться, либо потребует отдельного правила распределения.

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

Ключи фактов и справочников

После фиксации зерна проверьте ключи. У строки заказа редко бывает уникален один только OrderID, потому что в одном заказе несколько строк. Обычно нужен составной бизнес-ключ вроде OrderID + LineID. В таблице Orders, наоборот, OrderID должен быть уникален: одна строка на заказ, без дублей. У справочника товаров уникален ProductKey, у календаря — ключ даты, у клиента — CustomerKey.

В Power BI связь один-ко-многим технически создается там, где на стороне one ключ уникален. Но сама возможность создать связь еще не делает модель корректной для отчета. Таблица Orders может стоять на стороне one по отношению к SalesLines, и это будет верно по ключу OrderID. Однако из этого не следует, что числовые поля Orders можно безопасно анализировать в разрезе товаров из SalesLines.

Практически полезно пройти короткий список до загрузки визуалов:

  • для каждой таблицы записан смысл одной строки;
  • для стороны one проверена уникальность ключа;
  • для стороны many подтверждено, что повторения ожидаемы;
  • числовые поля отмечены по уровню: строка заказа или заказ целиком;
  • каждый справочник связан напрямую с тем фактом, который он должен фильтровать.

Последний пункт часто недооценивают. Если вы хотите анализировать продажи по товарам и датам на уровне строк, не стоит надеяться, что таблица Orders станет «мостом» от календаря к строкам и автоматически решит все фильтры. Намного надежнее, когда общий справочник даты и другие нужные измерения подключены к тем фактам, для которых вы строите меры.

Проверка итогов на двух заказах

Учебный пример. Ниже условные данные для проверки в Power BI Desktop. Таблица SalesLines хранит продажи на уровне строки заказа, а Orders — итог по заказу. Все числа условные, но арифметика согласована.

SalesLines.OrderIDLineIDProductKeyQtyLineAmount
10011A2400
10012B1600
10021A1500
Orders.OrderIDCustomerKeyOrderAmount
1001C11000
1002C2500

Связь между таблицами: Orders[OrderID] — сторона one, SalesLines[OrderID] — сторона many. Для первичной проверки достаточно трех мер:

Продажи по строкам = SUM ( SalesLines[LineAmount] )

Сумма заказов = SUM ( Orders[OrderAmount] )

Сумма заказов, повторенная на строках =
SUMX ( SalesLines, RELATED ( Orders[OrderAmount] ) )

Третья мера намеренно «опасная»: она переносит итог заказа в контекст строк. Именно так легко поймать двойной счет еще до отчета. Проверка по двум заказам должна дать такой результат:

OrderIDПродажи по строкамСумма заказовСумма заказов, повторенная на строках
1001100010002000
1002500500500
Итого150015002500

Почему получилось 2500 вместо 1500? Заказ 1001 имеет две строки. Когда вы тянете OrderAmount в строковый контекст, сумма 1000 повторяется дважды: один раз для товара A, второй — для товара B. Для заказа 1002 повторения нет, потому что строка одна. Это и есть проверяемый симптом смешения уровней детализации.

Полезно сделать вторую сверку по товарам. Для товара A продажи по строкам равны 900, а повторенная сумма заказов будет 1500, потому что в товар A попали оба заказа. Для товара B продажи по строкам равны 600, а повторенная сумма заказов — 1000. Если такой разрыв вы видите на учебных двух заказах, в полном наборе данных ошибка станет только менее заметной, но не исчезнет.

Что делать при разных уровнях детализации

Первый безопасный вариант — оставить две отдельные факт-таблицы и не смешивать меры. Тогда вы считаете выручку по товарам из SalesLines, а показатели уровня заказа — из Orders. Это не «магическое исправление», а дисциплина модели: каждая мера живет на своем уровне. Если авторы отчетов могут случайно брать не те поля, шапочные числовые столбцы лучше явно скрыть или оставить только через продуманные меры.

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

Третий вариант нужен, если заказный показатель действительно надо анализировать на уровне строк или товаров. Тогда без отдельного бизнес-правила не обойтись. Например, скидку заказа можно распределять пропорционально сумме строк или поровну по строкам. Но это уже не следствие модели и не свойство звездной схемы само по себе, а выбранная логика распределения. Ее надо зафиксировать, посчитать на маленьком наборе заказов и проверить арифметику: сумма распределенных значений по строкам должна возвращать исходную сумму по заказу.

Практический результат такой проверки очень конкретный: до построения отчета вы уже знаете, что одна строка в SalesLines — это строка заказа, одна строка в Orders — это заказ, OrderID уникален только в Orders, а поле OrderAmount нельзя без дополнительного правила переносить в товарный контекст. Это экономит время не потому, что Power BI что-то исправит сам, а потому, что вы ловите логическую ошибку до того, как она превратится в «красивый, но неверный» дашборд.

Если вы хотите отдельно потренировать именно подготовку данных и связи в Power BI, по официальной программе Нетологии подтверждены темы Power Query, создание модели данных, вычисления и связывание данных из разных источников. Краткая карточка программы в каталоге: «Инструменты для анализа данных».

Курсы

11138
0,0
0 отзывов
Инструменты для анализа данных
  • c 12 октября
  • 6 месяцев
  • Онлайн
  • Диплом / Сертификат
75 600 ₽168 000 ₽
-55%
Перейти на сайт