首页 > 解决方案 > 在 DAX 中,为什么 ALL 过滤器在应用于组时会被覆盖

问题描述

在我的事实表中,我有一列以整数分钟表示两个日期时间值之间的时间差。我还创建了一个组(通过左键单击仪表板视图中的 [Difference_min] 列并选择新组)以更好地显示时间间隔的差异。在表格视图中,它看起来像这样:

在此处输入图像描述

我使用一个简单的度量来计算我的数据表中的行数,并将其显示为总数的百分比,以查看基于间隔分组的时间差分布:

NumberOfRows = COUNTROWS('Data')

在此处输入图像描述

首先,我通过添加 [Difference_min] 列作为切片器来删除空白值 (Tom),然后选择除空白值之外的所有值。
然后我只想看两个最高时差组的百分比。我复制我的直方图并在可视切片器窗格中仅选择30 - 3940+,然后我编写一个像这样的适当百分比度量并将其添加到新视觉对象中:

NumberOfRows_pct = 
DIVIDE(
    [NumberOfRows];
    CALCULATE(
        [NumberOfRows];
        ALL('Data'[Difference_min (group)])
    );
    0
)

我最终得到了这个(绿色=仅计数功能,黑色=除法功能):

在此处输入图像描述

绿色条是正确的(或者至少是我期望看到的),尽管我预计黑色的值与上图中的值相同,即分别为 7.5 % 和 4.8 %。

但是,如果我删除 [Difference_min] 上的过滤,NumberOfRows_pct 度量的行为与我预期的一样:

在此处输入图像描述

问题
为什么 [Difference_min] 上的过滤/切片会取消
ALL('Data'[Difference_min (group)])百分比度量中的效果?

pbi 示例文件:pbi 文件

标签: powerbidax

解决方案


您看到的是DAX 自动存在优化的结果。

要理解这一点,请考虑以下查询,这些查询类似于 Power BI 用于呈现条形图的查询。第一个查询不包含 [Difference_min] 不应为空的条件,但第二个查询包含它:

DEFINE
VAR __DifferenceMinGroupFilter = TREATAS({"30 - 39"} , 'Data'[Difference_min (group)])
VAR __DifferenceMinFilter = FILTER(VALUES('Data'[Difference_min]), NOT ISBLANK('Data'[Difference_min]))

// Query 1 (no filter on [Difference_min]):
EVALUATE
SUMMARIZECOLUMNS(
    'Data'[Difference_min (group)],
    __DifferenceMinGroupFilter,
    "NumberOfRows", [NumberOfRows],
    "NumberOfRows_pct", [NumberOfRows_pct]
)

// Query 2 (with filter on [Difference_min]):
EVALUATE
SUMMARIZECOLUMNS(
    'Data'[Difference_min (group)],
    __DifferenceMinGroupFilter,
    __DifferenceMinFilter,
    "NumberOfRows", [NumberOfRows],
    "NumberOfRows_pct", [NumberOfRows_pct]
)

以下是这两个查询对 Power BI 文件产生的结果,问题显示在查询 #2 上:

在此处输入图像描述

在这种情况下您必须使用的原因ALL('Data')是因为自动存在优化会影响查询 #2。从我上面链接的文章中:

当同一个表的两个或多个列被过滤在一起时,自动存在机制就会启动。SUMMARIZECOLUMNS 不会将列用作单独的过滤器,而是仅生成一个过滤器,该过滤器仅使用现有的值组合过滤所有列。

因此,在评估度量时,您实际上在 [Difference_min] 列上有一个过滤器,当 [Difference_min (group)] 为“30 - 39”时,它仅包含该列中的值,因为这两个列都位于同一列上桌子。

因此,仅使用 ALL 删除 [Difference_min (group)] 列上的过滤器是不够的。您必须将您的度量修改为:

NumberOfRows_pct = 
DIVIDE(
    [NumberOfRows],
    CALCULATE(
        [NumberOfRows],
        ALL('Data'[Difference_min (group)]),
        NOT ISBLANK('Data'[Difference_min])  // Overrides the filter from outside
    ),
    0
)

推荐阅读