CALCULATE(m, x=red)
和CALCULATE(m, KEEPFILTERS(x=red))
有什么区别
显然它们并不相同。我找到了文档和说明,但仍然不明白。
https://docs.microsoft.com/en-us/dax/keepfilters-function-dax
答案 0 :(得分:4)
没有KEEPFILTERS
的情况下,您的第一个度量将覆盖应用于字段x
的所有其他过滤器。
第二个度量使用KEEPFILTERS
维护字段x
上的过滤器上下文,并将新的过滤器上下文作为现有过滤器的子集应用(或空白,如果过滤器上下文没有重叠)。 / p>
这是一个简单的PBIX文件示例,用于演示-使用颜色切片器,并查看两种测量方法的区别:https://pwrbi.com/so_57850298/
这个SQLBI.com article解释得很好。
答案 1 :(得分:2)
更多地了解如何评估CALCULATE
中的简单谓词是有帮助的。以下两个表达式是等效的;实际上,第一个只是语法糖,第二个-前者在幕后被重写为后者:
CALCULATE ( [m], 'T'[Col] = "Red" )
和
CALCULATE (
[m],
FILTER (
ALL ( 'T'[Col] ),
'T'[Col] = "Red"
)
)
FILTER
是一个迭代器,该迭代器将表作为第一个参数,将要在行上下文中求值的谓词作为第二个参数。它将从谓词为false的输入表中删除所有行。
因此,CALCULATE
对过滤器上下文的操作实际上几乎完全是对表的操作。如果您对关系代数感到满意,则CALCULATE
的args2-N中的表是与CALCULATE
的arg1中的表达式中要操作的表半连接的表。这些半联接取决于数据模型中定义的关系。
因此FILTER ( ALL ( 'T'[Col] ), <predicate> )
的模式将忽略'T'[Col]上的任何外部过滤器上下文,并将其替换为您定义的新过滤器上下文。
现在KEEPFILTERS
。我不是100%肯定这只是语法糖,但我相信是。无论哪种方式,下面的两个表达式在语义上都是等效的-它们将始终返回相同的值:
CALCULATE ( [M], KEEPFILTERS ( 'T'[Col] = "red" ) )
和
CALCULATE (
[M],
FILTER (
VALUES ( 'T'[Col] ), // this is the only difference from the first expansion
'T'[Col] = "red"
)
)
您可以看到KEEPFILTERS
扩展正在使用VALUES
而不是ALL
。因此,ALL
将返回命名列中的所有唯一值,而忽略该列上的任何过滤器上下文(它还有其他形式可以在一个以上的列上进行操作,但这与本讨论无关)。 VALUES
返回当前过滤器上下文中命名列的唯一值。
另一种思考方式如下。假设值“ red”确实存在于“ T” [Col]中。 FILTER ( ALL ( 'T'[Col] ), 'T'[Col] = "red" )
将始终返回值为'red'的1列1行表'T'[Col]。 FILTER ( VALUES ( 'T'[Col] ), 'T'[Col] = "red" )
将始终返回一个1列的表,其中包含0行或1行;如果外部过滤器上下文包含“ T” [Col] =“ red”,则它将返回具有'T'[Col] =“ red”的1行表,而如果外部过滤器上下文不包含该值,它将返回空表。
同样,以上FILTER
表达式的表输出被视为左侧半联接中的右侧表。
尤其要注意,以上所有内容均基于单列。如果有多个列构成过滤器上下文,则可能会引发循环。这是一个易于理解的示例。我们定义了两个度量,并将它们放入带有'DimDate'[Year]和'DimDate'[Date]的表格中。
Prior Date =
VAR CurrentDate = MAX ( 'DimDate'[Date] )
RETURN
CALCULATE (
MAX ( 'DimDate'[Date] ),
'DimDate'[Date] = CurrentDate - 1
)
Prior Day ALL DimDate =
VAR CurrentDate = MAX ( 'DimDate'[Date] )
RETURN
CALCULATE (
MAX ( 'DimDate'[Date] ),
ALL ( 'DimDate' ),
'DimDate'[Date] = CurrentDate - 1
)
这是它们在表格视觉中返回的内容:
在DAX中定义了带有日期的算术,<date> - 1
将始终返回先前的日期。因此,2019年1月1日的CurrentDate - 1
是2018年12月31日。但是在我们的视觉效果中,我们同时具有来自'DimDate'[Year]和'DimDate'[Date]的过滤器上下文,因此在第一个度量中,我们正在'DimDate'[]的过滤器上下文中计算MAX ( 'DimDate'[Date] )
Year] = 2019和'DimDate'[Date] = 2018-12-31(CALCULATE
中的上下文操作)。 'DimDate'中没有同时匹配这两个条件的行,因此第一个版本返回空白。第二个版本清除了所有来自'DimDate'的过滤器上下文,因此剩下的唯一上下文是我们在'DimDate'[Date] = CurrentDate - 1
中明确应用的内容。
请注意,上面的示例仅在使用KEEPFILTERS
时返回总计值。
Prior Date KEEPFILTERS =
VAR CurrentDate = MAX ( 'DimDate'[Date] )
RETURN
CALCULATE (
MAX ( 'DimDate'[Date] ),
KEEPFILTERS ( 'DimDate'[Date] = CurrentDate - 1 )
)
这仅适用于总计,因为在详细级别,KEEPFILTERS ( 'DimDate'[Date] = CurrentDate - 1
无法返回任何值。就是说,本质上是“找到一个比自己少的日期”,这显然是不可能的。但是总的来说,上下文中有许多日期,因此我们正在筛选包含许多连续日期的表。因此,我们的度量值可以返回总计值。