https://zhuanlan.zhihu.com/p/64418286
假设有一组数据,
已知每一个产品贡献的利润,如果要计算前几名产品的贡献利润总和,或者每一个产品和利润更高产品的累计贡献占总体的比例,就涉及到累计求和,数据量较小的情况下,在 Excel 中可以轻松实现,毕竟 Excel 是对单元格进行操作。
但是在 PowerBI 中,对整个字段运算很简单,而对每一行的数据进行筛选汇总,却需要动一点小心思,下面就以此表为例介绍几种常用的累计求和方式,并以此案例来进一步掌握几个函数的用法。
利用 M 函数累计求和
将该数据导入到 PQ 编辑器中,添加自定义列,
公式栏中输入M函数,
=List.Sum(Table.SelectRows(更改的类型,(x)=>x[利润]>=[利润])[利润])
然后就新增加了一列累计利润,
对这里的公式稍微解释一下,
Table.SelectRows 函数用来筛选表中符合条件的行,"更改的类型"是表的名称,在PQ编辑器中,每一个步骤就是一个表,步骤名就是该表的名称。
(x)=>x[利润]>=[利润]是筛选条件,这个相对比较难理解,还记得之前介绍的自定义函数吗,见到=>这个符号,就代表这里有个自定义函数,只是在这里是内置函数。意思为每一行为变量x,只要第x行的利润数大于等于当前行的利润,就利用 Table.SelectRows 函数把改行筛选出来。
而 Table.SelectRows 函数返回的是一个表,如果要提取该表中利润列,就是在该函数外面再加上字段名进行深化,于是就有了 Table.SelectRows(更改的类型,(x)=>x[利润]>=[利润])[利润],它返回的是符合条件的利润列。
最后再在最外面套上 List.Sum 函数对该列进行求和,就得到了以上表中累计利润。
利用 DAX 进行累计求和
在 DAX 中可以用 EARLIER 函数和 VAR 定义变量两种方式。
使用 EARLIER 函数
累计利润2 =
CALCULATE(SUM('产品'[利润]),
FILTER(ALL('产品'),'产品'[利润]>=EARLIER('产品'[利润])))
EARLIER函数以前专门介绍过,可以参考:EARLIER 函数 | PowerBI星球
使用VAR定义变量的方式累计求和
累计利润3 = VAR cur_profit='产品'[利润]
RETURN CALCULATE(SUM('产品'[利润]),
FILTER(ALL('产品'),'产品'[利润]>=cur_profit))
这两种方式返回的结果和利用M函数的效果完全一致,
这两种函数,其实和上面M函数一样,都是通过各自的方式筛选符合大于等于当前利润的数据行,然后求和得到结果。
上面的DAX求和用到的是CALCULATE,其实这里也可以用SUMX函数,
累计利润4 = SUMX(filter(all('产品'),'产品'[利润]>=EARLIER('产品'[利润])),'产品'[利润])
累计利润5 = VAR cur_profit='产品'[利润]
RETURN SUMX(FILTER(ALL('产品'),'产品'[利润]>=cur_profit),'产品'[利润])
CALCULATE函数第一个参数是汇总方式,第二个及之后的参数为筛选条件,而SUMX函数第一个参数筛选条件,第二个参数为求和字段,在求和的计算上,SUMX可以实现和CALCULATE一样的效果。
案例中的数据已经按照利润从大到小进行排列,理解上更直观,其实即使不进行排序,这几种方式也都可以返回正确的结果,因为计算的逻辑和每一行的顺序无关。
上面几个公式,需要的时候可以随时套用,当然在理解的基础上灵活掌握这些函数,可以更有效的进行各种数据分析。累计求和在数据分析中十分常用,比如ABC分析,后面会进一步介绍。