【Power BI 基础】Filter+All 以及Calculate+filter 方法的使用

目的:得到每一年的Gowrth Rate!

=calculate(计算式,条件1,条件2,。。。,条件n)

首先GrowthRate:=CY Sales/PY Sales-1, (今年的sales/去年的Sales-1),今年的Sales很简单,我们做Measure1,SalesValue:=sum(data[sales]),轻松完成!(就是上边的图了)

然后最大的挑战就来了,去年的Sales怎么弄出来呢?

1.    先写一个过渡的Measure:

                           ALL Sales:= CALCULATE([SalesValue],ALL(data[year]))  

                          (这里大家可以看到,计算式不仅仅可以是个公式,也可以是其他的一个Measure!)

这里的条件是ALL(data[year]) ALL的意思很简单,就是把一个表里边所有的筛选(filter)取消掉,返回一张没有筛选的表。

比如我写个Dax,ALL Sales 2:=calculate([SalesValue], All(data)),得到的效果就是不管Pivot表里边怎么筛选(年份也好,产品也好,什么也好),得出来的数据就是所有Sales的总和。

这里用ALL(data[year])的意思呢,就是只有Year这一个列的筛选我不想要,其他产品,顾客什么的,我还是要滴。所以意思就是得到所有年份Sales的总和。

下图里边大家就可以比较出ALL(data[year])ALL(data)的区别了吧!

【Power BI 基础】Filter+All 以及Calculate+filter 方法的使用_第1张图片

2.   上第二个条件吧!

      =CALCULATE([SalesValue],ALL(data[year]),FILTER(all(data[year]),data[year]=VALUES(data[year])-1))

Filter是和Calculate绝配的DAX,能设置复杂的条件要求。它的格式是:

                             =Filter(表或列,条件)

比如之前2013 Sale的例子,你也可以写成2013 Sales 2:=calculate([SalesValue],filter(data,data[year]=2013))。但像这种简单的条件就不用Filter出马了。(其实不是完全等价的,这里卖个关子:))

回到这个例子,"表"就是All(data[year]) (为什么又加ALL呢?卖第二个关子!),条件是data[year]=VALUES(data[year])-1,这就是传说中的Year=Year-1啦。

Data[year]指的是我们原始Data表中的Year列,而Values[data[year]指的是Pivot Table中的Year。比如Pivot中是2012,那就是告诉Measure,你要去找Data表里所有(2012-1=)2011的Sales。

而为什么Pivot的Year要加一个Values呢?

Data[year]指的是一个列,里边有很多很多的数据。比如之前2013 Sales的例子,Data[year]=2013,你是告诉找到这个列的所有等于2013的Year的行,注意,列=数值,多对单的关系。

这个例子里,同样,你要告诉data[year]取某个数值,但你不能说:data[year]=data[year],列=列,多对多的关系,这样Measure就完全晕了,直接返回一个错误。所以右边一定是一个单一的值,Values的意思就是这样了,会返回一个列的所有唯一值。这个例子里呢,就是返回{2011,2012,2013}总共三个值。

 

但又要注意了,Pivot里边已经把Year放在了列里边,所以在Pivot中,2011行只会返回{2011},2012行只会返回{2012},2013行只会返回{2013}。(这里的Data[year]就千万不要加ALL了,要不出来就是{2011,2012,2013}三个值了)

但是如果你没有把Year列放在Pivot的列中,Values返回来的就是{2011,2012,2013}。Data[year]={2011,2012,2013}就是可空集了(没有一个行即等于2011,又等于2012,还等于2013吧?)。

3.   其实这时候大部分的问题已经解决了,我们来说一下之前卖的关子,FILTER(all(data[year]),data[year]=VALUES(data[year])-1)中的all(data[year])为什么要加ALL

 

其实原理有二:

首先,Calculate里边的所有条件的级别都是一样的,不是说条件1摆在前边就会对条件2产生限制,所以即便条件1已经定义了ALL(data[year]),但Filter里边的Data[year]还是被Pivot筛选过后的Data[year],所以ALL必须加上。我们可以把ALL和Filter这两个条件调换一下,你会发现结果完全一样的。

 

然后问题又来了,既然Filter里边的Data[year]已经有ALL了,为什么还需要条件1的ALL(data[year])呢?其实这是关于Filter的特殊属性的,只减不加!什么意思呢?

 

如果条件是Data[year]=2013,这种不是Filter的条件,会粗暴地强行改变Pivot已经设置的条件的,所以在2013 Sales的例子里,2011-2013都只会显示2013的Sales。

而Filter呢,如果你写成

2013 Sales 2:=calculate([SalesValue],filter(data,data[year]=2013))

 

你会看到2011,2012是没有数的,因为Filter不会增加或者强行改变Pivot中已经设置的条件的,只会在其基础上做减少

【Power BI 基础】Filter+All 以及Calculate+filter 方法的使用_第2张图片

图4

所以,既然Pivot已经做了年份的筛选,想要做到前一年的Sales,只能先把Data表用ALL把年份的筛选给去掉,然后再用Filter弄成前一年的筛选条件,只减不加就体现在这里。

4.   最后,DAX公式的完整版是:

 PY Sales:=

   IF(HASONEVALUE(data[year]),

   CALCULATE([SalesValue],ALL(data[year]),FILTER(all(data[year]),data[year]=VALUES(data[year])-1)),BLANK())

加了一个IF,请直译,如果Data[year]只有一个值(HAS ONE VALUE),那么咱们来算上年的Sales,否则就Blank。HASONEVALUE完全等价于Count(Values(data[year]))=1。Blank()相当于Excel里的””。

所以如果Pivot里边不定义年份,那就是有多个年份了,公式就会返回一个Blank,就不出现啦。

5.   最后的Growth Rate也就水到渠成啦:

                      Growth Rate = Iferror([SalesValue]/[PY Sales]-1,Blank())

 

就算把SalesValue和PY Sales去掉,Growth也照样可以出来!而且2011行自动消失了哦(因为没有2010的数据,所以算不出PY Sales,是个Error,返回Blank(),就消失啦!)

 

Filter  函数深入理解

度量值工作的两大核心步骤是筛选计算,筛选函数是制定计算的范围,聚合函数的用途是计算。如果你能够领悟第一阶段学习的筛选聚合共8个函数以及上下文的概念,你就掌握了度量值和DAX的精髓左手漏斗筛选器右手智能计算器,随心所欲的设计你的筛选和计算,Master of Power BI指日可待。

=calculate(计算式,条件1,条件2,。。。,条件n), Calculate 函数已经有了筛选功能,为什么还要用Filter?这是学习Filter时大多数人的第一反应。其实Filter才是真正意义的筛选器,其筛选能力远大于Calculate附带的筛选功能,我们常见的筛选利用Calculate完成而不是用Filter,完全是因为杀鸡焉用牛刀。就好像求1+1=2,我们没有必要用电脑来计算。

我们先说说Calculate的局限性,在Calculate中的直接筛选条件里我们只能输入[列]=固定值(>,<,= 等运算符同样适用)这种类型的条件。比如求咖啡种类=”拿铁”, 价格>=30的销售数量,写公式=Calculate([销售量],[咖啡种类]="拿铁";, [价格]>=30)。

这个很容易,然而如果我们想要求季度销售数量超过200杯的分店的销售数量求和呢?有点不知所措了吧,总结来说,当出现如下的类型时,Calculate中的直接筛选就不可用了,这个时候我们不得不求助于更强大的Filter函数。

PowerBI公式-Filter 函数-3.jpg (27.12 KB, 下载次数: 0)

2  Filter的工作原理
首先我们知道,Filter不是计算函数,是筛选函数,返回的结果是一张,所以无法单独使用,经常与Calculate搭配,也可以直接与某些聚合函数搭配,比如Countrows(filter(表,筛选条件))来计算表行数。Filter的语法是很简单的,第一部分的表可以是任意一个表,包括上一节学习的All()函数返回的表,甚至可以再嵌套一个Filter返回的表; 第二部分筛选条件是结果为真或假的表达式。

PowerBI公式-Filter 函数-4.png (26.34 KB, 下载次数: 0)

 

先用一个最简单的例子,Calculate([销售量],[咖啡种类]="拿铁";, [价格>=30),这个公式,我们也可以用Filter来完成,即Calculate([销售量],Filter('咖啡数据',[咖啡种类]="拿铁"&&[价格]>=30)(&& 表示两个条件为AND和的关系,即需要同时满足两个条件)
我们再回到前面的那个问题,如果想要求季度销售数量超过200杯的分店的销售数量,你可能会想到传统的Excel分析方式,利用数据透视表先找到每个季度销量超过200杯的城市,再去求那些城市的销售量总计,然而这个过程太麻烦,对于度量值这只是秒秒钟解决的事情。现在我们用Filter添加一个新的度量值[销售量7] =  Calculate([销售量],filter('区域负责人名单',[销售量]>=200)),得到如下结果,说明从2016年的第2季度开始才有超过200杯销售量的分店出现。

PowerBI公式-Filter 函数-5.jpg (111.88 KB, 下载次数: 0)



Filter与我们前面学习的7个函数不同,它对所筛选的表进行逐行的横向扫描,针对每一行循环地执行设定的筛选程序,我们把这类函数叫做Iterator, "迭代函数",后面第三阶段将要学习的SUMX等带X类的函数以及Earlier函数都属于迭代函数。它们与其他函数的主要区别就是在工作的时候可以意识到它所指的是哪一行, 我们把这个工作叫做创造行上下文

PowerBI公式-Filter 函数-6.jpg (86.23 KB, 下载次数: 0)


需要注意的是,迭代函数很强大,但是因为它强大的计算能力,我们使用的时候要格外小心。逐行的运算,意味着它们可以触到表中的最细的一层颗粒度。想象以下上面的数据例子,如果区域负责人表里有100个城市,测算每个城市的[销售量]是否>200的计算就会分别执行100次,再乘以最终输出表中单元格的数量。所以如果你筛选的表是在有上百万行的数据表中进行,这就可能有千万级亿级次的计算量,你的电脑可能会因为庞大的计算量而吃力。所以在使用Filter这个函数时有两个特别嘱咐:
1. 尽量在Lookup表,而不在数据表。(同我们使用的数据例子,区域负责人名单的数据量远远小于咖啡数据表的量)

2. 当Calculate的直接筛选功能可以完成工作时,一定不要用Filter。前面提到Calculate的筛选条件只能执行[列]=固定值这一类的计算,当应对这一类筛选运算时,简单的Calculate运算起来最快。杀鸡焉用牛刀,只有当Calculate自己搞不定的时候,我们再用Calculate+Filter的方法。

 

 

 

你可能感兴趣的:(Power,BI)