DAX从入门到精通 3-4-1 了解filter函数
了解filter函数
filter函数很简单:传入一个表格,然后返回一个和原来列相同的表格,但是只会保留符合条件的行。
filter的语法如下:
FILTER ( <table>, <condition> )
filter函数对table进行迭代,每行都会判断是否符合条件,然后返回布尔值。当条件为true的时候,filter返回该行,否则跳过。
注意:
从逻辑角度出发,filter函数对table表每行执行条件判断。但是DAX内部在执行判断的时候,会使用优化的处理方式,会使用对列去重的方式来减少判断的数量。判断的数据,实际上是等于filter函数处理表的粒度。这个粒度情况决定的了filter函数的性能,这个也是一个DAX优化的一个重要点。
例如,下面这个查询只选择brand = "Fabrikam":
EVALUATE
FILTER (
Product,
Product[Brand] = "Fabrikam"
)
image.png
可以在filter函数内嵌套filter函数,因为可以使用一个表函数来作为filter的参数。filter首先执行的是最内部的filter,通常,嵌套两个过滤器会产生相同的结果和使用AND函数中包含的逻辑条件的组合相同。也就是,下面的语句会得到相同的结果:
FILTER ( <table>, AND ( <condition1>, < condition2> ) )
FILTER ( FILTER ( <table>, < condition1> ), < condition2> ) )
但是,这两个公式在table表含有非常多行或者非常复杂的时候,性能会有很大的差距。例如下面这个查询,返回价格是成本三倍的fabrikm的产品。
EVALUATE
FILTER (
Product,
AND (
Product[Brand] = "Fabrikam",
Product[Unit Price] > Product[Unit Cost] * 3
))
image.png
这样的查询会把两个条件都添加到product表的所有行进行判断。因此,你可以更改下,如果你有两个条件,其中一个运行更快且更容易,你可以使用filter的嵌套形式,先处理这个过滤条件。例如。下面的查询,先过滤了price和cost,然后再过滤brand = ‘Fabrikam’,最终达成结果。
EVALUATE
FILTER (
FILTER (
Product,
Product[Unit Price] > Product[Unit Cost] * 3
),
Product[Brand] = "Fabrikam"
)
如果你调整一下顺序,那么执行的顺序也调整了。如下的先过滤了‘Fabrikam’,然后再过滤price和cost。
EVALUATE
FILTER (
FILTER (
Product,
Product[Brand] = "Fabrikam"
),
Product[Unit Price] > Product[Unit Cost] * 3
)
这点对于DAX表达式的优化非常有用。你可以选择先运行更高效的过滤条件。但是,在没有完全掌握上下文的时候,不要开始使用这种方法来优化语句。在第16章中,我们会深入的讨论这个优化。这个案例的作用只是让你意识到嵌套时候的运算顺序。
划重点:
通常情况下,对于嵌套的函数,顺序总是从最内部开始然后向外到最外部。但是calculate和calculatetable不同,这个是因为对于参数的特殊评估条件。很多情况下,我们会在相似的情况下使用filter和calculatetable函数,使用的时候我们要注意它们的区别。