PowerBI之DAX神功:第2卷第4回 不连续日期情况下计算移动平均值
上节课我们提到,大多数情况是下面这样不连续日期的销售表,我只删除了A商品2021/1/3的销售记录,咱们假设2021年1月3日这一天A商品没人来买。

我们先使用上节课的度量值,测试一个问题:
【度量值】平均销量 = AVERAGE('销售表'[销量])

我们以A商品为例,它没有2021/1/3的销售,所以这里就不显示
【度量值】平均销量 = AVERAGE('销售表'[销量])
这个度量值的筛选功能,大家应该很熟悉
以前我们经常用SUM,现在用AVERAGE,只是聚合方法不同,原理相同。
接下来我们回忆一下,上节课的【近3天移动平均3】这个度量值:
【度量值】近3天移动平均3 = CALCULATE([平均销量],FILTER(all('日期表'),'日期表'[日期]>max('日期表'[日期])-3 && '日期表'[日期]<=MAX('日期表'[日期])))

计算过程:
1日,1/1=1
2日,(1+2)/2=1.5
3日,(1+2)/2=1.5
#因平均销量根本就没有第3日,所以第3日的移动平均仍然是(1+2)/2=1.5
4日,(2+4)/2=3 # 同理
5日,(4+5)/2=4.5 #同理
6日,(4+5+6)/3=5
……………….以此类推
综上所述,我们的度量值【近3天移动平均3】当平均销量为空时,这一天不记做分母
我们反过来说这句话:为什么没有记录的这一天不记做分母?
因为:【平均销量】在被日期筛选时,就看不到这一天

有些人有业务需求,如本案例所示,他们需要将平均销量为Blank()的看做是0
模拟计算过程:
1日,1/1=1
2日,(1+2)/2=1.5
3日,(1+2+0)/3=1
4日,(2+0+4)/3=2
5日,(0+4+5)/3=3
6日,(4+5+6)/3=5
……………..以此类推
思路:做一个类似【平均销量】功能的度量值,需要体现出没有销售的那一天
小学2年级数学老师教的:任何数除以1等于原数
【度量值】总销量 = sum('销售表'[销量])

【总销量】这个度量值与我们刚才【平均销量】是一样的,A商品第3日无销售就被过滤掉了
【度量值】日期表总行数 = COUNTROWS('日期表')

上节课,我让大家使用动态方法创建日期表
你的日期表中,起止日期由销售表日期列决定,且日期表中的日期必然连续。
无论你A商品第3日是否有销量,都不会影响【日期表总行数】这个度量值
《DAX神功》 第1卷第4回.常见错误与处理方法 我们讲到如下概念
Blank() / 1 =Blank()
Blank()/Blank()=Blank()
经过四则运算后的blank()默认是0
【度量值】辅助列后的销量 = SUM('销售表'[销量])/COUNTROWS('日期表')

【度量值】近3天移动平均6 = CALCULATE(sum('销售表'[销量])/COUNTROWS('日期表'),FILTER(all('日期表'),'日期表'[日期]>max('日期表'[日期])-3 && '日期表'[日期]<=MAX('日期表'[日期])))

学习知识和学习语言不同的地方,例如英语你知道正确发音就不用问为什么这么读了?
但是知识不行,既然讲原理,咱们就讲到你休克为止。
大家想一想,如果我这样写:
【度量值】日期表总行数2 = COUNTROWS(Values('销售表'[日期]))

是不是A商品第3日的被筛选没了?
为什么?因为销售表中A商品没有3日的销售呗。
【度量值】近3天移动平均7 = CALCULATE(sum('销售表'[销量])/COUNTROWS(Values('销售表'[日期])),FILTER(all('日期表'),'日期表'[日期]>max('日期表'[日期])-3 && '日期表'[日期]<=MAX('日期表'[日期])))

看上去:是不是等价我们的【近3天移动平均3】
你可能会想,如果你上来就这样讲,多简单,两种分母情况就全部解决了
你看总计了吗?我并不推荐这种方法
你这样做处理起来很麻烦,如果想实现这种效果用【近3天移动平均3】就好了

但是,度量值【近3天移动平均6 】这种写法,我们别无选择
有两种方法处理总计问题
方法一:让总计为空:
【度量值】近3天移动平均8 = if(Hasonevalue('日期表'[日期]),[近3天移动平均6])

用在图表上可以,用在矩阵上就奇怪了
方法二:让明细行显示[近3天移动平均6],让总计行显示【近3天移动平均3】
【度量值】近3天移动平均3=CALCULATE([平均销量],FILTER(all('日期表'),'日期表'[日期]>max('日期表'[日期])-3 && '日期表'[日期]<=MAX('日期表'[日期])))
【度量值】近3天移动平均9 = if(Hasonevalue('日期表'[日期]),
[近3天移动平均6],CALCULATE([平均销量],FILTER(all('日期表'),'日期表'[日期]>max('日期表'[日期])-3 && '日期表'[日期]<=MAX('日期表'[日期]))))
Ps: 我将【近3天移动平均3】写到【近3天移动平均9】里面,是告诉大家没必要写两个度量值,摆在这里只是让大家看清楚,IF的第3参数是什么。


各位听众,你们有没有一种想哭的感觉?这刚哪到哪呀?最多就三分之一的教程。
为什么《孙兴华讲PowerBI火力全开》坚持不讲原理,你们明白吗?
对于毫无基础的人讲原理,劝退率99.99%
对于有基础的人讲原理,劝退率85%以上。
原理,需要有强大的逻辑思维支撑,否则即便今日听懂,也很难灵活运用。

《孙兴华讲PowerBI火力全开》PowerBI必学课程
https://www.bilibili.com/video/BV1qa4y1H7wp
《DAX神功》文字版合集:
https://www.bilibili.com/read/readlist/rl442274
《DAX神功》视频版合集:
https://www.bilibili.com/video/BV1YE411E7p3
PowerBI(DAX函数)、PowerQuery(M函数)、Python办公自动化、Python爬虫、Python数据分析、ExcelVBA、WordVBA、AccessVBA、MySQL等等