高级筛选器 Filter函数
度量值工作的两大核心步骤是筛选和计算,筛选函数是制定计算的范围,聚合函数的用途是计算。如果你能够领悟第一阶段学习的筛选和聚合共10个函数以及上下文的概念,你就掌握了度量值和DAX的精髓。左手漏斗筛选器,右手智能计算器,随心所欲的设计你的筛选和计算,Master of Power BI指日可待。这一节我们就来学习最强大的筛选函数Filter。
1
Filter 与 Calculate
CALCULATE(<计算式>,<筛选条件1>,<筛选条件2>…)已经有了筛选功能,为什么还要用Filter?这是学习Filter时大多数人的第一反应。其实Filter才是真正意义的筛选器,其筛选能力远大于Calculate附带的筛选功能,我们常见的筛选利用Calculate完成而不是用Filter,完全是因为杀鸡焉用牛刀。就好像求1 1=2,我们没有必要用电脑来计算。
先说说Calculate的局限性,在Calculate中的直接筛选条件里我们只能输入[列]=固定值(<>等运算符同样适用)这种类型的条件。比如求咖啡种类=”拿铁”, 价格>30的销售数量,写公式=Calculate([销售量],[咖啡种类]="拿铁", [价格]>30)。
这个很容易,然而如果我们想要求季度销售数量超过200杯的分店的销售数量求和呢?有点不知所措了吧,总结来说,当出现如下的类型时,Calculate中的直接筛选就不可用了,这个时候我们不得不求助于更强大的Filter函数。
2
Filter的工作原理
首先我们知道,Filter不是计算函数,是筛选函数,返回的结果是一张表,所以无法单独使用,经常与Calculate搭配,也可以直接与某些聚合函数搭配,比如Countrows(filter(表,筛选条件))来计算表行数。
Filter的语法是很简单的,第一部分的表可以是任意一个表,包括上一节学习的All()函数返回的表,甚至可以再嵌套一个Filter返回的表; 第二部分筛选条件是结果为真或假的表达式。
Calculate([销售量],[咖啡种类]="拿铁", [价格]>30),这个公式,我们也可以用Filter来完成,即Calculate([销售量],Filter('咖啡数据',[咖啡种类]="拿铁"&&[价格]>30) (&&表示两个条件为AND和的关系,即需要同时满足两个条件)。
我们再回到前面的那个问题,如果想要求季度销售数量超过200杯的分店的销售数量,你可能会想到传统的Excel分析方式,利用数据透视表先找到每个季度销量超过200杯的城市,再去求那些城市的销售量总计,然而这个过程太麻烦,对于度量值这只是秒秒钟解决的事情。
现在我们用Filter添加一个新的度量值[销售量7] = Calculate([销售量],filter('区域负责人名单',[销售量]>200)),得到如下结果,说明从2016年的第2季度开始才有超过200杯销售量的分店出现。
Filter与我们前面学习的9个函数不同,它对所筛选的表进行逐行的横向扫描,针对每一行循环地执行设定的筛选程序,我们把这类函数叫做Iterator, "迭代函数",后面第三阶段将要学习的SUMX等带X类的函数以及Earlier函数都属于迭代函数。
它们与其他函数的主要区别就是在工作的时候可以意识到它所指的是哪一行, 我们把这个工作叫做创造行上下文。
需要注意的是,迭代函数很强大,但是因为它强大的计算能力,我们使用的时候要格外小心。逐行的运算,意味着它们可以触到表中的最细的一层颗粒度。
想象以下上面的数据例子,如果区域负责人表里有100个城市,测算每个城市的[销售量]是否>200的计算就会分别执行100次,再乘以最终输出表中单元格的数量。所以如果你筛选的表是在有上百万行的数据表中进行,这就可能有千万级亿级次的计算量,你的电脑可能会因为庞大的计算量而吃力。所以在使用Filter这个函数时有两个特别嘱咐:
1. 尽量在Lookup表,而不在数据表。(同我们使用的数据例子,区域负责人名单的数据量远远小于咖啡数据表的量)
2. 当Calculate的直接筛选功能可以完成工作时,一定不要用Filter。前面提到Calculate的筛选条件只能执行[列]=固定值这一类的计算,当应对这一类筛选运算时,简单的Calculate运算起来最快。杀鸡焉用牛刀,只有当Calculate自己搞不定的时候,我们再用Calculate Filter的方法。