KEEPFILTERS函数仅用在Calculate函数(或者Calculatetable函数)中,作用是修改Calculate函数缺省的覆盖外部上下文的工作方式。
微软官方的解释如下:
计算 CALCULATE 或 CALCULATETABLE 函数时,修改应用筛选器的方式。
https://learn.microsoft.com/zh-cn/dax/keepfilters-function-dax
我们之前介绍Calculate函数时已经看到过它的作用了(见这里)。
本文简单介绍一下这个函数的具体应用方式。
下面的两个度量值展示了对于单条件的筛选器使用这个函数的作用:
Contoso Sales Amount = CALCULATE( Sales[Sales Amount], 'Product'[BrandName] = "Contoso")
Contoso Sales Amount 4 = CALCULATE( Sales[Sales Amount], KEEPFILTERS('Product'[BrandName] = "Contoso"))
数据结果如下:
上一次我们介绍了,也可以不使用KEEPFILTER函数,而是采用对Product表进行筛选的方式,
Conto Sales Amount 3 = CALCULATE( [Sales Amount], FILTER( 'Product', 'Product'[BrandName] = "Contoso" ) )
这个度量值同样保持了外部筛选器上下文的作用。
但是这个写法需要筛选Product表,有效率的问题。我们可以使用VALUES函数,
Conto Sales Amount 5 = CALCULATE( [Sales Amount], FILTER( VALUES('Product'[BrandName]), 'Product'[BrandName] = "Contoso" ) )
Values函数返回一列中的所有值,听起来跟All函数一样,但是它接受外部筛选器上下文的影响。
如果有多个筛选条件,它们的作用原理是一样的。比如下面的两个度量值,
Contoso Or Deluxe Sales Amount = CALCULATE( [Sales Amount], 'Product'[BrandName] = "Contoso" || 'Product'[ClassName] = "Deluxe" )
Contoso Or Deluxe Sales Amount 3 = CALCULATE( [Sales Amount], KEEPFILTERS('Product'[BrandName] = "Contoso" || 'Product'[ClassName] = "Deluxe") )
它们的计算结果如下:
如果不想使用keepfilters函数,你也不能像前面的例子中那样使用values函数,因为这个函数的参数只能是1列或者一个表,而不能是多个列,
这里可以使用下面的写法,
Contoso Or Deluxe Sales Amount 4 = CALCULATE( [Sales Amount], 'Product'[BrandName] = "Contoso" || 'Product'[ClassName] = "Deluxe", SUMMARIZE('Product', 'Product'[BrandName], 'Product'[ClassName]) )
可以看到,我们多加了一个筛选器参数,这个参数中使用的是summarize函数。这也是一个很有意思的函数,我们以后再介绍。目前你只要理解它在这里的作用就是对Product表进行分组就可以了,分组依据是品牌名称和类别名称,返回一张表,这个表被用作 calculate函数的筛选器参数。
作用到多个筛选条件(不同列)时
当有多个筛选条件,并且作用到不同列上时,我们只能采用如下写法:
Contoso Or Asia Sales Amount = CALCULATE( [Sales Amount], FILTER( CROSSJOIN(ALL('Product'[BrandName]), ALL('Geography'[ContinentName])), 'Product'[BrandName] = "Contoso" || 'Geography'[ContinentName] = "Asia" ))
此时,并没有像之前那种同一个表上的多个条件那种简单写法,那应该如何使用keepfilters函数呢?
很简单,用在筛选表上就可以了,
Contoso Or Deluxe Sales Amount 1 ALLKEEP = CALCULATE( [Sales Amount], KEEPFILTERS( FILTER( ALL('Product'[BrandName], 'Product'[ClassName]), 'Product'[BrandName] = "Contoso" || 'Product'[ClassName] = "Deluxe" )) )
用在其他函数中
SUMX( KEEPFILTERS(VALUES('Product'[BrandName])), [Sales Amount] )
一个小问题
这里的Contoso Sales Amount 4是使用了keepfilters的结果。
这里的问题是:
既然度量值Sales Amount就是会介绍外部筛选器上下文的影响,那么为什么又需要专门做一个keepfilters修饰的度量值呢?为什么不直接在切片器或者其他筛选器中只显示Contoso的数值呢,
联系客服