Найти тему
Место #13

Как посчитать количество заказов с 2мя товарами в Power BI?

Оглавление

В данной статье я хочу показать 3 способа получения количества заказов, в которых содержатся сразу 2 определенных товара, в Power BI на языке DAX. Весь пример будет строится на базе данных AdventureWorksDW2019.

Обратимся к модели данных, которую я сделал в отчете для демонстрации.

Модель данных Power BI
Модель данных Power BI

Здесь всего 2 таблицы: Таблица фактов - FactResellerSales, которая содержит продажи, и таблица измерений - DimProduct - Номенклатура. Данные объекты соединены связью "многие к одному". Связь однонаправленная, что будет учтено при создании примеров.

Мы будем определять наличие сразу 2х товаров в заказе по следующим SKU:

  • "HL Touring Frame - Yellow, 46",
  • "HL Touring Frame - Yellow, 50".

Способ №1

Прежде, чем преступить к коду, опишу предложенный алгоритм:

  1. Определим множество заказов для первого товара.
  2. Определим множество заказов для второго товара.
  3. Найдем заказы, которые есть в первом и втором множествах.
  4. Посчитаем количество строк получившегося пересечения.
Код на языке DAX.
Код на языке DAX.

Для расчет переменных __sku_1 и sku_2 используем функцию CALCULATETABLE() к качестве первого элемента функции используем VALUES().

Для нахождения пересечения данных множеств используем функцию INTERSECT(), которая оставляет нам только те заказы, которые есть в обеих таблицах. А затем просто считаем количество строк, т.к. в таблице __intersect содержатся только уникальные значения.

Результат
Результат

В результате вы можете увидеть только те заказы, в которых содержатся наши товары. Они у нас промаркированы единицей. Остальные не учитываются.

Способ 2

Данные способ представляет собой итеративный подход к решению этой задачи. Вот его алгоритм:

  1. Определим список всех заказов и начнем "проход" по каждому из них.
  2. В каждом будем вычислять уникальное количество наименований с по нашему списку позиций
  3. Определим условие, что, если количество наименований = 2, то засчитываем этот заказ, иначе - BLANK()
  4. Возращаем результат условия и подводим итог.
Код на языке DAX. Способ 2
Код на языке DAX. Способ 2

В данном случае у нас код получился чуть компактнее, но это, вовсе, вовсе не означает, что алгоритм производительнее. О производительности стоит поговорить в отдельной статье.

В этом коде используется итерирующая функция COUNTX() (на самом деле можно использовать и SUMX() ). В первом элементе функции мы определяем весь пул заказов, которых у нас есть в данном контексте фильтра. Далее каждый заказ у нас фильтрует модель и мы считаем количество уникальных товаров для каждого номера заказа с учетом фильтра по названию продукта. Очевидно, что мы ищем значение равное 2. Найдя это значение в условии, мы обозначаем его единицей, для остальных присваиваем BLANK(). Результат условия возвращаем, и функция COUNTX() считает итог.

Такой подход нужно использовать аккуратно, т.к. итерирование часто ухудшает производительность.

Результат
Результат

Как видим, результат получился тот же: итог совпадает, заказы, которые содержат только 1 наименование, не учитываются.

Способ 3

В данном способе алгоритм следующий:

  1. Создаем вычисляемую таблицу, которая содержит все заказы.
  2. Добавляем 2 столбца, которые считают наличие первого и второго товара в заказе
  3. Фильтруем получившуюся таблицу и считаем количество оставшихся строк
Код на языке DAX. Способ 3
Код на языке DAX. Способ 3

В данном способе мы используем функцию ADDCOLUMNS(). В качестве табличного аргумента используем нашу любимую функцию VALUES(). Для столбцов "sku 1" и "sku 2" считаем наличие каждой SKU в заказе. Получив вот такую большую таблицу мы ее фильтруем проверяя, что расчетные столбцы содержат данные. Далее по отфильтрованной таблице считаем количество строк и проверяем результат.

Результат
Результат

Как видите, результат тот же.

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

Если у вас есть идеи, напишите о них в комментариях. На этом все.