如何在 Power BI 桌面中参数化聚合列?

How to parameterize a column for aggregation in Power BI desktop?

我有一些用户希望能够修改 table 聚合的列。我的问题是我似乎无法在 Power BI 中执行此操作。我基本上希望能够在 SQL:

中执行以下操作
SELECT
    <OrgLevel1>,
    <OrgLevel2>,
    SUM([Revenue])
FROM [Data]
GROUP BY
    <OrgLevel1>,
    <OrgLevel2>
;

用户可以将 <OrgLevel1> and/or <OrgLevel2> 更改为 { "(All)", [Department], [Product] } 中的任何一个。

问题可能与此相关post:https://community.powerbi.com/t5/Desktop/Calculated-Column-Table-Change-Dynamically-According-to-Slicer/m-p/655991#M314800

这里有一个 link 工作簿来说明这个问题,TestParameterizeGroupby.pbix(由 Google 云端硬盘托管)。我还在下面的屏幕截图中包含了字段定义。感谢您的帮助。

TestParameterizeGroupby.pbix

Link:TestParameterizeGroupby.pbix(由 Google 驱动器托管)

问题

[Org Level 1][Org Level 2] 字段不会根据用户的选择重新计算。仅显示默认值。

预期结果 table

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

备注

目的是拥有可参数化的组织级别字段,以便报表用户可以按所有、部门、产品或两者按任一顺序进行汇总。

Table 和列定义

'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)

Table 'Org Level 1' 与 [组织级别 1 参数] 列上的 'Org Level 1 Parameter' 具有 1-1 关系。

用户通过选择 'Org Level 1'[组织级别 1] 的值来选择 'Data'[组织级别 1] 的值。

Table[组织级别 2] 的列和列的定义方式与 [组织级别 1] 相同。

截图

报告视图:

数据查看:

模型视图:

Power BI 论坛中对 post 的交叉引用: Power BI Forum: How to parameterize a column for aggregation

对此的一种解决方案是添加两个列表值参数并在 Power Query M 代码中使用它们的值来修改数据库查询。假设您有一个包含 DepartmentProductRevenue 列的 table Data。为简单起见,我将再添加一列,命名为 Dummy Column,所有行都具有相同的值(例如 null)。我将在稍后解释原因post。所以 table 看起来像这样:

然后在您的报告中指定一个查询,将此 table 添加到您的模型(假设我们将导入它,但通常您也可以在 DirectQuery 中执行此操作):

现在,如果您查看 M 代码,您会在那里看到上面的查询:

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

现在定义几个参数,最终用户可以使用这些参数 select 如何聚合数据。让我们将它们命名为 Level 1Level 2:

参数的值可以通过参数名在M中使用,&用于拼接字符串。因此,如果存在值为 Samuel 的参数 Name,则表达式 "Hello, " & Name & "!" 将被计算为 Hello, Samuel!。这个想法是检查我们参数的值并相应地修改数据库查询。

在 select 部分,我们将替换字段的名称 selected,或者我们将在 <All> 的情况下放置 ''(空字符串) (我用括号将参数值括起来,以便更容易将参数值与数据库字段名称区分开来)。所以表达式应该是这样的:

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

因为我们的参数名中有一个space,我们需要用#""将它包围起来,所以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)

所以最后的M代码是这样的:

let
    Source = Sql.Database(".", "Whosebug", [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:

来更改参数值

和select如何分组数据:

默认情况下,Power BI Desktop 会在执行特定查询时第一次警告您:

如果要关闭此功能,请转到 File -> Options and settings -> Options -> (GLOBAL) Security 并确保 Require user approval for new native database queries 是未 selected:

当最终用户改变参数值时,数据也会改变,例如:

或:

等等...

当每个用户都有自己的 .pbix 文件副本时,此技巧在 Power BI Desktop 中效果很好。但是,如果您发布它,首先更改参数值不是很方便(您必须去 datasat 的设置),更重要的是,更改参数值会影响所有正在查看此报告的用户。您还可以使用它来修改 Power Query 编辑器生成的 Table.Group 语句,以防您想在 Power BI 中聚合数据,但更改数据库查询更容易、更灵活。

如果要为已发布报告的并发多用户场景启用此场景,可以使用切片器和 What-if parameters。不幸的是,What-if 参数可以是数字(您不能在那里定义值列表),因此您可以使用度量 "decode" 参数的 int 值并编写一些 DAX 代码以相应地执行不同的聚合。比较费工夫,但如果需要,也可以制作。