评估此Filter(All(Column),...)语法后,真正发生了什么?

时间:2019-04-24 15:06:35

标签: powerbi dax

在PowerBI Desktop模型中,只有一个名为“ Data”的表,其中包含[Datetime],[Type],[Name]和其他几列。

我通过单击图形来选择特定的Type =“ B”,并在Datetime上使用切片器选择一段时间,然后使用以下措施来计算类型“ A”中有多少个不同的名称(如预期,A和B不能同时记录。) 那时候我完全被结果弄糊涂了:

(我的PowerBI版本是2019年4月的最新版本。)


Wrong =
CALCULATE (
    DISTINCTCOUNT ( Data[Name] ),
    FILTER ( ALL ( Data[Type] ), Data[Type] = "A" )
)

这是正确的选择,

Correct = 
CALCULATE ( 
    DISTINCTCOUNT ( Data[Name] ), 
    FILTER ( Data, Data[Type] = "A" ) 
)

我认为正在发生的事情(可能缺少重要的内容):

由于这两个度量在CALCULATE之外共享相同的显式过滤器上下文,并且它们最终计算出的结果是相同的,所以唯一的问题将是“ FILTER提供的最终上下文是什么”?

在使用正确版本的情况下,FILTER仅使用(Type =“ B” + Datetime)子集,尝试在子集内查找类型为“ A”的行(Type =“ B” + Type =“ A “ + Datetime),它只会失败。因此,FILTER并没有给最终的计算带来任何好处,结果证明是空白的(当我选择Type B时应该没有A Type记录。)

在错误版本中,FILTER(只有一列)会忽略Type(最初为“ B”)上的所有过滤器上下文,然后应用新的过滤条件(Type =“ A”)来替换原始的。并且由于每个列都是单独过滤的,因此Datetime上的过滤器根本不会更改。因此,CALCULATE接受的最终上下文应该是包含类型“ A”和同时选定的时间段(Type =“ A” + Datetime)的子集,从而使最终结果为“类型A的唯一名称”,与我最初选择的类型无关。


但是,根据它给出的奇怪结果,事实是[Wrong]绝对不是我在想的,我对此一无所知。我尝试了许多我认为合理的方法来测试其工作方式,但是它们只是失败了...

谢谢您的任何建议!


我制作了一个很小的pbix文件进行测试(具有相同的结构和问题): https://pan.baidu.com/s/1gNZDNlICFLkMdPpPArb8cQ 如果需要,请使用yf7f下载。

2 个答案:

答案 0 :(得分:2)

FILTER函数将表作为第一个参数。该表是在您操作的过滤器上下文中评估的。

Correct版本中,这意味着当您传入Data时,该表将根据切片器的选择在Type = "B"Datetime上进行过滤。然后,您添加条件Data[Type] = "A",这对于已过滤的Data集中的任何内容都不成立,因为您已经为类型选择了"B"。因此,由于表为空,因此返回空白。


编辑:刮开我之前说的内容,然后看一个示例。从此作为一个完整的表格开始:

Name  Type  Datetime
Alex  A     1/3/2019
Alex  A     1/4/2019
Bob   A     1/5/2019
Bob   B     1/5/2019
Bob   A     1/7/2019
Carla B     1/3/2019
Carla B     1/4/2019
Dan   A     1/6/2019

如果我对类型B和日期1/3/2019 - 1/5/2019进行切片,则剩下的行如下:

Name  Type  Datetime
Bob   B     1/5/2019
Carla B     1/3/2019
Carla B     1/4/2019

当我们在此上下文中计算ALL( Data[Type] )时,将获得下表,该表与您删除Type切片器但保留日期切片器的情况相同:

Name  Type  Datetime
Alex  A     1/3/2019
Alex  A     1/4/2019
Bob   A     1/5/2019
Bob   B     1/5/2019
Carla B     1/3/2019
Carla B     1/4/2019

现在,当您添加Data[Type] = "A"条件时,您将获得此表,该表与您最初在A而非B上进行过滤(并保留日期分割器)相同,您得到以下信息:

Name  Type  Datetime
Alex  A     1/3/2019
Alex  A     1/4/2019
Bob   A     1/5/2019

这显然有两个不同的名称,而不是没有。在Correct版本中,区别在于您在上面的第二个表而不是第3个表中过滤了类型A

基本上,ALL会撤消使用切片器选择的类型的选择。


注意:我之前所说的间接影响事物并不是这里发生的事情。当您执行从行上下文到过滤器上下文的上下文转换时,这是一个问题,但不适用于此处。抱歉造成混乱。

答案 1 :(得分:0)

最后,我找到了发生这种情况的原因! 这称为任意形状的滤波器的覆盖。 完整说明可在“ DAX权威指南”的第10章第439-443页中找到。

请小心在同一表的两列或多列上使用多个过滤器,这是可能导致问题的最简单方法!