В данной статье я хочу показать 3 способа получения количества заказов, в которых содержатся сразу 2 определенных товара, в Power BI на языке DAX. Весь пример будет строится на базе данных AdventureWorksDW2019.
Обратимся к модели данных, которую я сделал в отчете для демонстрации.
Здесь всего 2 таблицы: Таблица фактов - FactResellerSales, которая содержит продажи, и таблица измерений - DimProduct - Номенклатура. Данные объекты соединены связью "многие к одному". Связь однонаправленная, что будет учтено при создании примеров.
Мы будем определять наличие сразу 2х товаров в заказе по следующим SKU:
- "HL Touring Frame - Yellow, 46",
- "HL Touring Frame - Yellow, 50".
Способ №1
Прежде, чем преступить к коду, опишу предложенный алгоритм:
- Определим множество заказов для первого товара.
- Определим множество заказов для второго товара.
- Найдем заказы, которые есть в первом и втором множествах.
- Посчитаем количество строк получившегося пересечения.
Для расчет переменных __sku_1 и sku_2 используем функцию CALCULATETABLE() к качестве первого элемента функции используем VALUES().
Для нахождения пересечения данных множеств используем функцию INTERSECT(), которая оставляет нам только те заказы, которые есть в обеих таблицах. А затем просто считаем количество строк, т.к. в таблице __intersect содержатся только уникальные значения.
В результате вы можете увидеть только те заказы, в которых содержатся наши товары. Они у нас промаркированы единицей. Остальные не учитываются.
Способ 2
Данные способ представляет собой итеративный подход к решению этой задачи. Вот его алгоритм:
- Определим список всех заказов и начнем "проход" по каждому из них.
- В каждом будем вычислять уникальное количество наименований с по нашему списку позиций
- Определим условие, что, если количество наименований = 2, то засчитываем этот заказ, иначе - BLANK()
- Возращаем результат условия и подводим итог.
В данном случае у нас код получился чуть компактнее, но это, вовсе, вовсе не означает, что алгоритм производительнее. О производительности стоит поговорить в отдельной статье.
В этом коде используется итерирующая функция COUNTX() (на самом деле можно использовать и SUMX() ). В первом элементе функции мы определяем весь пул заказов, которых у нас есть в данном контексте фильтра. Далее каждый заказ у нас фильтрует модель и мы считаем количество уникальных товаров для каждого номера заказа с учетом фильтра по названию продукта. Очевидно, что мы ищем значение равное 2. Найдя это значение в условии, мы обозначаем его единицей, для остальных присваиваем BLANK(). Результат условия возвращаем, и функция COUNTX() считает итог.
Такой подход нужно использовать аккуратно, т.к. итерирование часто ухудшает производительность.
Как видим, результат получился тот же: итог совпадает, заказы, которые содержат только 1 наименование, не учитываются.
Способ 3
В данном способе алгоритм следующий:
- Создаем вычисляемую таблицу, которая содержит все заказы.
- Добавляем 2 столбца, которые считают наличие первого и второго товара в заказе
- Фильтруем получившуюся таблицу и считаем количество оставшихся строк
В данном способе мы используем функцию ADDCOLUMNS(). В качестве табличного аргумента используем нашу любимую функцию VALUES(). Для столбцов "sku 1" и "sku 2" считаем наличие каждой SKU в заказе. Получив вот такую большую таблицу мы ее фильтруем проверяя, что расчетные столбцы содержат данные. Далее по отфильтрованной таблице считаем количество строк и проверяем результат.
Как видите, результат тот же.
Лучший способ определить сложно, т.к. нужно анализировать модель данных. Конечно, можно придумать и другие способы решения данной задачи.
Если у вас есть идеи, напишите о них в комментариях. На этом все.