Страницы: 1
RSS
Мера для ТОП - N значений
 
Добрый день!
Подскажите пожалуйста, разобраться не могу никак.

Пытаюсь построить структуру продаж, в качестве визуализации выбор пал на Санкей, что в-принципе и обуславливает сложность.
Данные загружены в модель, и отображаются полосками по количеству.
При этом все "мелкие" значения мешают оценить общую картину.
За счёт применения фильтров на другие поля, перечень необходимых для оценки топ-5\10\N естественно меняется постоянно.

Мне кажется, что проблему можно как-то решить путем создания меры, содержащей перечень ТОП - значений и агрегирующей оставшиеся в "Другое".
Подскажите пожалуйста, возможно ли и как это прописывать? Не нахожу данной функции никак.
Спасибо!
 
Доброе время суток
Цитата
Solomatnikov написал:
Не нахожу данной функции никак
Просто вы пока ещё не умеете готовить. А искать волшебное заклинание, вместо обучения...
 
Цитата
Андрей VG написал:
Просто вы пока ещё не умеете готовить
Однако же учусь, в том числе благодаря и Вам.
Спасибо!

Возможно ли при этом помещение этой группы "прочее" не в отдельную категорию, а среди прочих?

 
Цитата
Solomatnikov написал:
Возможно ли
Возможно.
 
Подскажите пожалуйста где поискать как это делать.
 
Опять поискать? :)  А как же изучить? Dynamic segmentation, ну, и, естественно, ПОДРОБНОЕ РУКОВОДСТВО ПО DAX
 
буду изучать.
Спасибо за отсылку к группе динамической сегментации - не догадался, что это именно оно.
Вот тут еще этот блок отыскал:

P.S. За ссылку на справочник DAXа тоже спасибо.
 
Цитата
Андрей VG написал:
искать волшебное заклинание
Искал галочку чтоб таблицу перевернуть вниз головой и не нашел. То есть Максимальные справа шли сверху вниз, а не снизу вверх как сейчас. Как это сделать?
 
Цитата
Виктор А написал:
Как это сделать?
Честно говоря, не знаю - обратитесь к разработчикам, может что и подскажут или добавят такую возможность в новой версии, если действительно не возможно.
 
Для решения задачи пошел по следующему пути, изучив меру Андрея:

1. Создание сводной таблицы по полю "Сумма" с группировкой по двум столбцам "Группа" и "Наименование".
2. Добавления столбца ранга
3. Разделение этой таблицы на две:
3.1. Ранг больше 5
3.2. Ранг меньше 5
4. В таблице с рангом меньше 5 (3.1.)
4.1. Создание сводной таблицы по полю "Сумма" с группировкой по одному столбцу "Группа"
5. Добавление столбца "наименование", содержащей значение "Другое" и столбца "Ранг" со значением "6"
6.  Объединение этих таблиц.



И вроде и работает это, в DaxStudio следующее:



Но при этом столбцы сползают и при попытке вернуть в PowerBI в меру, тот ругается на невозможность преобразовтаь значения в скалярное значение.

Подскажите пожалуйста кто в теме, где косяк? Как исправить?

P.S. За почерк или кривую логику - сильно не пинайте пожалуйста. Они оба - врачебные, уж извините.
Изменено: Solomatnikov - 23.09.2020 18:21:44
 
Цитата
Solomatnikov написал:
где косяк? Как исправить?
Код
var Edin = union (AddRankMinSumName1, addRankMax)

return Edin

Edin - это таблица. А результат любой меры - скалярное выражение: число, текст, логическое значение, дата. То что вы описали ход ваших мыслей - это не плохо. Но! Это уместно только после того, как вы выполнили постановку задачи. Что вы хотели получить этой мерой?
 
Цитата
Андрей VG написал:
Что вы хотели получить этой мерой?
Я хотел получить значения для первых пяти (ТОП-5) строк по столбцу сумма, при этом объединив оставльные значения в блок "Другое".
Внимательно изучил и рекомендованные Вами материалы, и опыт коллег (здесь).

У меня получилось разобраться как выводить значения с необходимой мне группировкой в блок "Другое" при фиксированном разделении (как пример - значение по строке больше 5% в структуре общей суммы) - полученный результат во вложении.

И при этом я всё никак не могу перейти на следующий уровень и соотнести это со значениями ранга. Я вроде и ранги ввёл, и в фильтрации по нима разобрался, но не работает - и всё тут. Или пусто, или не раскладываются на скаляр.
Задача уже вроде кажется простой, но никак всё не решается.
Поскольку говорили, что PowerBI недоступен - перенес всё в Excel.

Параллельно возник еще один вопрос -
Почему Вами в блоке Return первым условием указывалось на единственность значений по двум столбцам '
Код
HASONEVALUE('Лист1'[Наименование]) && HASONEVALUE('Группы'[Группа])
- с какой целью это внесено?
Изменено: Solomatnikov - 27.09.2020 11:07:10
 
Ура!
Смог сделать.

Итоговая мера получилась следующая:
Код
Мера 5:=var Svodnaya = SUMMARIZE('Лист1'; 'Лист1'[Наименование]; "SVOD"; SUM('Лист1'[Сумма]))
-- Свод по полю "Наименование" с вычислением суммы по каждой строке 
var SvodRang = ADDCOLUMNS(FILTER(Svodnaya; TRUE()); "RANG"; rankx (FILTER(Svodnaya; HASONEVALUE('Лист1'[Группа]) = HASONEVALUE('Лист1'[Группа])); [SVOD]; [SVOD]))
-- Добавление поля "Ранг" с отдельной нумерацией по каждой группе

var OtherSum = sumx (FILTER (SvodRang; [RANG]>5); [SVOD])
-- Для значений в поле "Ранг" больше 5 - сумма по полю "СВОД"



return 
if (HASONEVALUE('Dynamic'[Dynamic]);
-- Если в перечне значений в динамической таблицe есть пересечение с Лист1[Наименование] - по сути, 1 - для значения "Другое", 0 - для всех остльных значений
if(VALUES('Dynamic'[Dynamic])= "Другие"; OtherSum; 
-- Для значения "Другие" отразить значение из таблицы OtherSum
var PersonSum = sumx(filter(SvodRang; 'Лист1'[Наименование]=VALUES('Dynamic'[Dynamic])); [RANG])
-- Для каждого значения из исходного поля "Наименование" - определяется значение по столбцу "Ранг"
return 
if(PersonSum<=5; SUMX ( FILTER( SvodRang; 'Лист1'[Наименование]=VALUES('Dynamic'[Dynamic])) ; [SVOD]); BLANK()))
-- Если это значение по столбцу "Рагн" меньше 5 - определяется значение по полю "Свод" и именно оно и отображается.
; BLANK())

Каким-то пародоксальным образом всё стопорилось на добавлении ранга
Код
RANKX(FILTER(stats1, 'Лист1'[Группа] = EARLIER('Лист1'[Группа])), [product amount], [product amount]))

Честно говоря, так и не смог разобраться, для чего Андрей VG использовал именно эту функцию.

Заменил на
Код
HASONEVALUE('Лист1'[Группа]) = HASONEVALUE('Лист1'[Группа])
и всё получилось.
Не исключаю, что синтаксис неправильный, однако проверил - работа корректна.

Теперь к первому вопросу, который озвучил выше, добавился второй - для чего DAX требует именно единственного значения?

Итоговый работающий результат - во вложении.  
Изменено: Solomatnikov - 27.09.2020 12:03:39
 
Попробуйте так
Код
=
VAR stats =
    SUMMARIZE(
        'Лист1';
        'Лист1'[Наименование];
        "product amount"; SUM( 'Лист1'[Сумма] )
    )
VAR top5 =
    TOPN( 5; stats; [product amount]; DESC )
VAR notTop =
    EXCEPT( stats; top5 )
RETURN
    IF(
        HASONEVALUE( 'Dynamic'[Dynamic] );
        VAR dynItem =
            VALUES( 'Dynamic'[Dynamic] )
        RETURN
            IF(
                dynItem = "Другие";
                SUMX( notTop; [product amount] );
                SUMX( FILTER( top5; 'Лист1'[Наименование] = dynItem ); [product amount] )
            );
        BLANK()
    )

P. S. Следует учесть следующий момент, если сумма в SUMMARIZE на порядке убывания для 6, 7 и так далее наименования будет равна пятому, то они будут тоже выводится. Если нужно строго только 5, то в TOPN добавьте порядок, например, по наименованию.
Изменено: Андрей VG - 27.09.2020 18:58:18 (Несколько компактнее и логичнее с точки зрения вычислений)
 
Попробовал.
Работает, спасибо!
Большое спасибо за помощь!

Можно пару вопросов?
Так и не смог разгадать почему Вы использовали именно эти значения в мере?

1. При добавлении столбца ранга
Код
ADDCOLUMNS (FILTER(stast, TRUE()); .....
Для чего проводится эта фильтрация на предмет TRUE?
Сколько не ковырял, разницы с использованием этого фильтра и без - не нахожу.

2. Там же, При добавлении столбца ранга
Код
RANKX(FILTER(stats1, 'Лист1'[Группа] = EARLIER('Лист1'[Группа])), [product amount], [product amount])) 
Для чего используется этот фильтр и почему внутри него именно EARLIER?
Изменено: Solomatnikov - 27.09.2020 19:33:00
 
Solomatnikov,

FILTER(stats1, 'Лист1'[Группа] = EARLIER('Лист1'[Группа])
Функция FILTER снимает весь контекст строки с таблицы stats1 (т.е. возращает всю таблицу)
Функция EARLIER возвратит значение столбца [Группа] из контекста строки на уровень выше и вернет единственное значение из исходной таблицы
После этого таблица stats1 будет отфильтрована по этому значению и ранг будет расчитан от суммы по группе товара

По этому для
FILTER(stast, TRUE())

Функция FILTER снимает весь контекст строки с таблицы
Это функция-итератор, проходит по каждой строке и сравнивает с логическим выражением для контекста строки из второго аргумента для функции (FilterExpression)
Оставляет строки которые соответствуют выражению
Так как в FilterExpression в данном примере находится TRUE(), то возвращается вся таблица

Попробуйте в таблице 'Лист1' добавить столбец с такой формулой
Код
CALCULATE(SUM('Лист1'[Сумма]),FILTER('Лист1',TRUE()))

А потом уберите из нее функцию FILTER

Изменено: DrillPipe - 28.09.2020 08:30:23 (Описание функции filter)
 
Цитата
DrillPipe написал:
Функция FILTER снимает весь контекст строки с таблицы stats1 (т.е. возращает всю таблицу)
ничего она не снимает, не путайте. Разве что вы под "снимает" понимаете не очистку (игнорирование) фильтров, а что-то другое.
F1 творит чудеса
 
Понял!
Спасибо!

И раз уж разговор пошел про детали, спрошу.
Создание таблицы с уникальными значениями: я на этапе тестирования и отработки создавал таблицу в PowerQuery путем
Код
= List.Sort(List.Distinct(Table.Column(Источник, "Наименование"))) & {"Другие"}

Наверняка как-то можно это сделать моделированием?
Не подскажете как, потому что везде DAX`овский DataTable описан только как создание таблицы из конкретных значений, а каждый раз в блок загрузки лазить - не есть гуд...
 
Solomatnikov, вы про это? Но вообще, это уже вопрос для отдельной темы.
Изменено: PooHkrd - 28.09.2020 11:00:42
Вот горшок пустой, он предмет простой...
 
Принято, спасибо!
Страницы: 1
Наверх