Как параметризовать столбец для агрегирования в Power BI Desktop? - PullRequest
0 голосов
/ 10 января 2020

У меня есть пользователи, которые хотели бы иметь возможность изменять, по каким столбцам агрегируется таблица. Моя проблема в том, что я не могу сделать это в Power BI. Я в основном хочу иметь возможность сделать следующее в SQL:

SELECT
    <OrgLevel1>,
    <OrgLevel2>,
    SUM([Revenue])
FROM [Data]
GROUP BY
    <OrgLevel1>,
    <OrgLevel2>
;

, где пользователь может изменить <OrgLevel1> и / или <OrgLevel2> на любой из {"(All)", [Department] , [Product]}.

Проблема может быть связана с этим сообщением: https://community.powerbi.com/t5/Desktop/Calculated-Column-Table-Change-Dynamically-According-to-Slicer/m-p/655991#M314800

Вот ссылка на книгу, иллюстрирующую эту проблему, TestParameterizeGroupby.pbix (размещен на Google Диске). Я также включил определения полей ниже со скриншотами. Спасибо за помощь Поля [Org Level 1] и [Org Level 2] не пересчитываются по выбору пользователя. Отображаются только значения по умолчанию.

Ожидаемый результат в таблице

"Org Level 1", "Org Level 2", "Revenue"
"(All)", "(All)", 28

Примечание

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

Определения таблиц и столбцов

'Data' = DATATABLE(
    "Department",
    STRING,
    "Product",
    STRING,
    "Revenue",
    DOUBLE,
    {
        {"DeptA", "ProdX", 5.0},
        {"DeptA", "ProdY", 6.0},
        {"DeptB", "ProdX", 10.0},
        {"DeptB", "ProdY", 7.0}
    }
)

'Data'[Org Level 1] = SWITCH(
    'Org Level 1 Parameter'[Org Level 1 Parameter Value],
    0,
    "(All)",
    1,
    [Department],
    2,
    [Product]
)
// Problem: [Org Level 1] and [Org Level 2] fields are not recalculating from the users' selection. Only the default values are shown.
'Org Level 1' = DATATABLE(
    "Org Level 1",
    STRING,
    "Org Level 1 Parameter",
    INTEGER,
    {
        {"(0) (All)", 0},
        {"(1) Department", 1},
        {"(2) Product", 2}
    }
)
'Org Level 1 Parameter'[Org Level 1 Parameter] = GENERATESERIES(0, 2, 1)
'Org Level 1 Parameter'[Org Level 1 Parameter Value] = SELECTEDVALUE('Org Level 1 Parameter'[Org Level 1 Parameter], 1)

Таблица «Уровень организации 1» имеет отношение 1-1 с «Параметр уровня организации 1» в столбце [Параметр уровня организации 1].

Пользователь выбирает значение для «Данные» [Уровень организации 1], выбирая значение для «Уровень организации 1» [Уровень организации 1] .

Таблицы и столбцы для [Уровень организации 2] определяются так же, как и [Уровень организации 1].

Снимки экрана

Просмотр отчета: Report

Просмотр данных: data

Вид модели: Model

Перекрестная ссылка на сообщение в форуме Power BI: Форум Power BI: Как параметризовать столбец для агрегирования

1 Ответ

2 голосов
/ 11 января 2020

Одним из решений этой проблемы является добавление двух параметров списка значений и использование их значений в коде Power Query M для изменения запроса к базе данных. Предположим, что у вас есть таблица Data со столбцами Department, Product и Revenue. Для простоты я добавлю еще один столбец с именем Dummy Column, в котором все строки имеют одинаковое значение (например, null). Я объясню почему позже в этом посте. Таким образом, таблица выглядит следующим образом:

enter image description here

Затем укажите в своем отчете запрос при добавлении этой таблицы в вашу модель (предположим, мы ее импортируем, но в целом вы можете сделать это и в DirectQuery):

enter image description here

Теперь, если вы посмотрите код M, вы увидите вышеупомянутый запрос:

Source = Sql.Database(".", "StackOverflow", [Query=" select ....

Теперь определите пару параметров, которые конечный пользователь может использовать для выбора способа агрегирования данных. Давайте назовем их Level 1 и Level 2:

enter image description here

Значение параметра можно использовать в М по имени параметра, а & используется для объединения строк. Поэтому, если есть параметр Name со значением Samuel, выражение "Hello, " & Name & "!" будет оцениваться как Hello, Samuel!. Идея состоит в том, чтобы проверить значение наших параметров и соответственно изменить запрос к базе данных.

В выделенной части мы заменим имя выбранного поля или добавим '' (пустая строка) в случай <All> (я заключил значения параметров в скобки, чтобы было легче отличить значения guish от имен полей базы данных). Таким образом, выражение должно выглядеть следующим образом:

"select " & (if #"Level 1" = "<Department>" then "Department" else ..." (and so on)

Поскольку в имени нашего параметра есть пробел, нам нужно заключить его в #" и ", поэтому на Level1 можно ссылаться просто как Level1 в коде, но Level 1 становится #"Level 1".

Группировать по частям немного сложнее. Мы должны добавить запятую между именами полей, добавить или не указывать имя поля или даже вообще не указывать group by (в случае, если оба параметра установлены на <All>). Чтобы упростить это, я добавил один фиктивный столбец, в котором все строки имеют одинаковое значение (например, null) и всегда группируем по этому столбцу. Таким образом, построение предложения group by гораздо проще - в случае, если значение параметра не равно <All>, мы должны добавить , fieldname. Таким образом, код может выглядеть следующим образом:

"group by DummyColumn" & (if #"Level 1" = "<Department>" then ", Department" else ..." (and so on)

Итак, окончательный код М выглядит так:

enter image description here

let
    Source = Sql.Database(".", "StackOverflow", [Query="select#(lf)    " & (if #"Level 1" = "<Department>" then "Department" else if #"Level 1" = "<Product>" then "Product" else "''") & " as [Org Level 1]#(lf)    , " &  (if #"Level 2" = "<Department>" then "Department" else if #"Level 2" = "<Product>" then "Product" else "''") & " as [Org Level 2]#(lf)    , SUM(Revenue) as Revenue#(lf)from Data#(lf)group by DummyColumn" & (if #"Level 1" = "<Department>" then ", Department" else if #"Level 1" = "<Product>" then ", Product" else "") & (if #"Level 2" = "<Department>" then ", Department" else if #"Level 2" = "<Product>" then ", Product" else "")])
in
    Source

Сейчас конечный пользователь может изменить значения параметров, нажав Edit Queries -> Edit Parameters:

enter image description here

и выберите способ группировки данных:

enter image description here

По умолчанию Power BI Desktop впервые предупредит вас при выполнении определенного запроса:

enter image description here

Если вы хотите отключить это, go до File -> Options and settings -> Options -> (GLOBAL) Security и убедитесь, что Require user approval for new native database queries не выбран:

enter image description here

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

enter image description here

Или:

enter image description here

И так далее ...

Этот прием хорошо работает в Power BI Рабочий стол, когда у каждого пользователя есть собственная копия файла .pbix. Однако, если вы опубликуете sh, сначала изменить значения параметров не очень удобно (вы должны go настроить параметры датасата) и, что более важно, изменение значений параметров затронет всех пользователей, которые просматривают этот отчет. Вы также можете использовать его для изменения операторов Table.Group, сгенерированных Power Query Editor, в случае, если вы хотите объединить данные в Power BI, но изменить запрос к базе данных проще и более гибко.

Если вы хотите включите этот сценарий для одновременного многопользовательского сценария ios для опубликованных отчетов, вы можете использовать срезы и параметры "что, если" . К сожалению, параметры «что-если» могут быть нумерацией c (вы не можете определить список значений там), поэтому вы можете использовать меры для «декодирования» значения int параметра и написать некоторый код DAX для выполнения различных агрегаций соответственно , Это больше работы, но если это необходимо, это тоже можно сделать.

...