#powerbi #powerbi-desktop
Вопрос:
У меня есть следующая таблица результатов в качестве источника данных:
Чего я хотел бы добиться, так это иметь визуальную таблицу с срезом, где пользователи могут выбирать дисциплину, а затем просматривать таблицу, отсортированную по столбцу результатов, показывая лучший результат на первом месте. В моем случае это означало бы:
- если выбрано 100 м, столбец результатов должен быть отсортирован по ASC, поскольку тип результата для этой дисциплины-ВРЕМЯ, то есть чем меньше значение, тем лучше результат
- если выбран прыжок в длину, столбец результатов должен быть отсортирован по порядку, поскольку тип результата для этой дисциплины-РАССТОЯНИЕ, то есть чем меньше значение, тем лучше результат
Я нашел здесь очень похожее решение, с одной проблемой: определение всех значений среза по одному было бы неэффективным — у меня много дисциплин. Я скорее подумываю об использовании disc_table, где тип результата определен для каждой дисциплины, и об использовании этой информации при настройке коммутатора.
Однако я действительно не знаю, как это должно быть закодировано в меру или если это вообще лучшее решение.
Спасибо за все ваши предложения!
ОБНОВЛЕНИЕ: Я только что заметил, что пропустил здесь важную часть. В таблице result_table есть скрытый столбец, содержащий результаты по времени, преобразованные в миллисекунды, и результаты по расстоянию, преобразованные в сантиметры. Это связано с тем, что некоторые дисциплины имеют результат в другом формате, например, на дистанции 1000 м он будет выглядеть так: 2:55,55. Таким образом, столбец результата относится к текстовому типу данных, но таблица фактически отсортирована по столбцу ConvertedResult и скрыта в визуальном (нулевая ширина)
Ответ №1:
У меня много дисциплин. Я скорее подумываю об использовании справочной таблицы, где тип результата определен для каждой дисциплины, и использовании этой информации при настройке коммутатора.
ДА. Вам действительно не нужно думать об этом с точки зрения слайсера. Просто напишите меру, которая генерирует правильный порядок. Используйте функцию SELECTEDVALUE для ссылки на текущее значение таблицы дисциплин.
Diciplines:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMjQwyFXSUQrJzE1VitWJVvLJz0tX8CrNLQAKumQWlyTmJQMlYgE=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Dicipline = _t, ResultType = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Dicipline", type text}, {"ResultType", type text}})
in
#"Changed Type"
и результаты:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMjQwyFXSUQoNdgSSlnqWZkqxOtFKPvl56QpepbkFcClTMwOwDFS9u1MQWL2FOYZ6iJSJEVB9LAA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Dicipline = _t, Country = _t, Result = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Dicipline", type text}, {"Country", type text}, {"Result", type number}}),
#"Merged Queries" = Table.NestedJoin(#"Changed Type", {"Dicipline"}, Diciplines, {"Dicipline"}, "Diciplines", JoinKind.LeftOuter),
#"Expanded Diciplines" = Table.ExpandTableColumn(#"Merged Queries", "Diciplines", {"ResultType"}, {"ResultType"}),
#"Added Conditional Column" = Table.AddColumn(#"Expanded Diciplines", "ResultDirection", each if [ResultType] = "Time" then -1 else if [ResultType] = "Distance" then 1 else null, type number),
#"Added Custom" = Table.AddColumn(#"Added Conditional Column", "ResultSort", each 1000000*[Result]*[ResultDirection], Int64.Type),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"ResultType", "ResultDirection"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Removed Columns",{{"Result", type text}})
in
#"Changed Type1"
Комментарии:
1. Спасибо, Дэвид, не могли бы вы сообщить мне более подробную информацию? Какой должна быть мера, как она «генерирует правильный порядок»? И куда я должен положить эту меру, когда она будет готова, в слайсер? Извините, я на самом деле не эксперт в Power BI (пока:)
2. Извините, я заметил, что пропустил кое-какую важную информацию. Я обновил исходный пост, не могли бы вы, пожалуйста, упростить предлагаемое решение?
Ответ №2:
DAX
если у вас есть следующая таблица
| Discipline | Country | Result |
|------------|---------|--------|
| 100m | USA | 9.69 |
| LJ | GBR | 560 |
| 100m | GBR | 9.87 |
| LJ | USA | 420 |
и у вас есть слайсер Discipline
, и вы хотите, чтобы мера сортировалась ASC
по ЖЖ и DESC
по 100м.
Вы можете сделать это, выполнив следующие действия
_sum = SUM('fact'[Result])
_rank =
SWITCH (
TRUE (),
SELECTEDVALUE ( 'fact'[Discipline] ) = "LJ", RANKX ( ALL ( 'fact'[Country] ), [_sum],, ASC ),
SELECTEDVALUE ( 'fact'[Discipline] ) = "100m", RANKX ( ALL ( 'fact'[Country] ), [_sum],, DESC )
)
Как только это будет сделано, перенесите все измерения в viz и отсортируйте, _rank
а затем Sort Ascending
Если вы прибегнете DAX
к этому, вам действительно нужно написать отдельные утверждения для каждой дисциплины внутри SWITCH
, и вы определяете желаемый порядок сортировки ранжирования внутри соответствующего RANKX
Комментарии:
1. Спасибо, пожалуйста, проверьте обновление в оригинальном посте — я пропустил важную часть.
2. При этом вам нужно выполнить агрегацию на
Converted Results
, аResult
не в_sum
.3. Итак, мне удалось это сделать, используя решение, указанное в моем первоначальном посте. Однако остается вопрос: вместо того, чтобы жестко кодировать все дисциплины в функции «ПЕРЕКЛЮЧАТЕЛЬ», есть ли способ использовать справочную таблицу и функцию «ПОИСК» в коммутаторе?
4. Таким образом, вы просите механизм DAX сгенерировать пользовательский порядок вашей агрегации
RANKX
. Этот пользовательский порядок определяется составителем отчета и в соответствии с дисциплиной. Следовательно, это должно быть явно упомянуто автором в тернарном операторе, таком какSWITCH
. Магия происходит внутриRANKX
. Но я не думаю, что вы можете передать строку с оператором RANKX в виде отключенного типаSWITCH (TRUE (),SELECTEDVALUE ( CAT[CAT]) = "LJ", MAX(CAT[Expression]),SELECTEDVALUE ( CAT[CAT] ) = "100m", MAX(CAT[Expression]))
, и все же это выражение будет оцениваться.5. Потому что на данный момент не существует такой вещи, как динамический DAX, как динамический SQL; например,
exec ('select 1 as col1, 2 as col2')
такой же, какSelect 1 as col1, 2 as col2
в TSQL.
Ответ №3:
Наконец я понял это, вот мера, которую я использовал вместе со справочной таблицей под названием «Дисциплины».
Ranking =
IF (
LOOKUPVALUE(Disciplines[ResultType], Disciplines[Discipline],
SELECTEDVALUE(Results[Discipline]))="T",RANKX(ALLSELECTED(Results),CALCULATE(SUM(Results[ConvertedResult])),,DESC),RANKX(ALLSELECTED(Results),CALCULATE(SUM(Results[ConvertedResult])),,ASC))