避免使用 FILTER 作为筛选器参数

作为数据建模者,通常你将编写需要在修改的筛选器上下文中计算的 DAX 表达式。 例如,你可以编写一个度量值定义来计算“高利润产品”的销售量。 本文稍后将介绍此计算。

注意

本文特别适用于应用筛选器导入表的模型计算。

CALCULATECALCULATETABLE DAX 函数是重要且有用的函数。 它们能让你编写删除或添加筛选器,或修改关系路径的计算。 这是通过在筛选器参数中传递完成的,筛选器参数是布尔表达式、表表达式或特殊筛选器函数。 我们仅在本文中讨论布尔和表表达式。

请考虑以下度量值定义,该定义使用表表达式计算红色产品销售量。 它将代替任何已应用于“产品”表的筛选器 。

Red Sales =
CALCULATE(
    [Sales],
    FILTER('Product', 'Product'[Color] = "Red")
)

CALCULATE 函数接受 FILTER DAX 函数返回的表表达式,该函数将为“产品”表的每一行计算其筛选器表达式 。 它得出了正确的结果 - 红色产品的销售量结果。 但是,使用布尔表达式可以更有效地实现此目的。

下面是改进后的度量值定义,它使用布尔表达式而不是表表达式。 KEEPFILTERS DAX 函数可确保任何应用到“颜色” 列的现有筛选器会保留,不会被覆盖。

Red Sales =
CALCULATE(
    [Sales],
    KEEPFILTERS('Product'[Color] = "Red")
)

建议尽量将筛选器参数作为布尔表达式传递。 这是因为“导入模型”表是内存中的列存储。 它们经过显示优化,可通过此方式高效筛选列。

但是,布尔表达式作为筛选器参数使用时,会存在一些限制。 它们:

  • 不能引用多个表中的列
  • 不能引用度量值
  • 不能使用嵌套 CALCULATE 函数
  • 不能使用扫描或返回表的函数

这意味着需要使用表表达式来满足更复杂的筛选要求。

现在请考虑一个不同度量值定义。 要求是计算销售额,但是仅针对获得利润的月份。

Sales for Profitable Months =
CALCULATE(
    [Sales],
    FILTER(
        VALUES('Date'[Month]),
        [Profit] > 0
    )
)

在此示例中,必须使用 FILTER 函数。 这是因为需要评估“利润”度量值,以删除没有获得利润的月份 。 将布尔表达式作为筛选器参数使用时,不能在其中使用度量值。

建议

为了获得最佳性能,建议尽量使用布尔表达式作为筛选器参数。

因此,只有在需要时才使用 FILTER 函数。 可以使用它来执行筛选器的复杂列比较。 这些列比较可能涉及到:

  • 度量值
  • 其他列
  • 使用 OR DAX 函数,或 OR 逻辑运算符 (||)