欢迎光临散文网 会员登陆 & 注册

Power BI之DAX神功:答网友问10 计算移动总计必先理解日期区间

2021-10-26 14:05 作者:孙兴华zz  | 我要投稿

一、网友提问

二、学习指导

还记得 《DAX神功》第2卷第3回 计算移动平均值再次理解Filter+ALL 吗?

那是我们在学习时间智能函数以前,计算移动平均值的方法

那篇文章一开始就告诉大家,关于计算移动平均值大家可以使用《孙兴华讲PowerBI火力全开》笔记 27.03  DATESINPERIOD函数

三、DATESINPERIOD函数详解

语法:DATESINPERIOD ( <日期列>, <起始日期>, <偏移量>, <间隔单位>)

返回:给定区间中的所有日期组成的单列形式的表

详细案例请看《火力全开》,这里我们只讲原理

以下表为例:

表名:Sheet1

例:从最大日期向前平移12个月

利用新建表测试:

表1 = DATESINPERIOD ('Sheet1'[日期], MAX ('Sheet1'[日期]), -1, YEAR )

表2 = DATESINPERIOD ('Sheet1'[日期], MAX ('Sheet1'[日期]), -12, MONTH )

Ps: 可以通过向前1年或向前12个月实现

我们肉眼看这张表,是不是取2019年7月1日~2020年6月1日(原表最大日期)这期间的所有日期

四、回答你在看书时遇到的疑惑

在《火力全开》笔记27课时我们讲了Datesbetween取某日期列中的区间值,书中是用这个函数来代替DATESINPERIOD,让你理解它的计算过程。说白了就是找到开始和结束日期取这一段日期的区间。

语法:Datesbetween(表[日期列],开始日期,结束日期)

1、结束日期我们可以通过MAX或LASTDATE得到:

表3= Datesbetween ('Sheet1'[日期],DATE(2019,7,1),MAX('Sheet1'[日期]))

表4 = Datesbetween ('Sheet1'[日期],DATE(2019,7,1),LASTDATE('Sheet1'[日期]))

以上两个表结果相同

问:网友又会产生疑问,《火力全开》第27课补充1:LastDate与max的区别 中讲到,MAX返回一个值,LastDate返回一张表,为什么这里LastDate可以代码结束日期?

答:详见《DAX神功》第1卷第10集 将表做标量值,LastDate返回最大日期那张表,最大日期只能有一个,所以是可以返回标量值的。即便你是多端表,有多个日期都是2020/6/1,LastDate函数最终只返回一个值的表。

2、开始日期的获取有问题,是因为你没有用日期表

《The Definitive Guide to DAX》上讲的获取开始日期的方法,只能获取连续日期

PS: 《DAX神功》答网友问08中提到时间智能函数第一参数可以是只有日期列的表,也可以是日期列。

因为我们表中没有2019年6月2日,上面公式返回的是空,当你用上面的公式做筛选条件时,相当于没有筛选条件,所以返回整个表的销售(1+2+...+15)=120  而不是114

在实际工作中,这样不连续的时间日期经常发生

我们需要的是2019年7月1日,在这个案例上你使用NEXTMONTH是可以得到2019/7/1

如果我的Sheet1表中最大日期是2020/6/2,你用上述方法就行不通了

现在你体会到DATESINPERIOD函数存在的意义了吗?

书中之所以这样写,因为他使用了日期表,日期表的时间肯定是连续的,当你使用日期表时,它就会找到2019/6/2~2020/6/1的区间做筛选条件,由于我表中是从2019年7月1日开始的,所以2019/6/2~2019/6/30不会返回任何值。就好比有三个都是2000年出生的人,我让你从他们当中找到1980~2010年之间出生的,你还是找到他们3个。

五、求移动平均值

《火力全开》中,我们学会了计算指定天数的移动平均值,也是最常用的,下表为《火力全开》笔记27课截图:

但是,你们想过没有,求30天、15天、7天的移动平均,是固定的数值,我们可以直接除以指定数值,其实还有一种省去了再除以固定值的方法。但是你要注意单位

例如,向前平移一年,就是移动了12个月,这时,我会要考虑年+月才能确定有多少个月

由于我们只使用了一张表,没有新建日期表,我们就在Sheet1中新建列,制造年月

【新建列】年月 = year('Sheet1'[日期])*100 + MONTH('Sheet1'[日期])

因为我们的表格是一端表,在实现工作中大多数情况是多端表,所以要考虑年月列的去重计数

Distinctcount('Sheet1'[年月])  //可以计算去重后的年月列有多少行,就是总计有多少个月

(1+2+...+15)/ Distinctcount('Sheet1'[年月])  //月平均销售

综上所述:我们可以将度量值写成下面两种方式:

近12个月的移动平均1 = CALCULATE([总销售],DATESINPERIOD('Sheet1'[日期],MAX('Sheet1'[日期]),-1,YEAR))/12

近12个月的移动平均2 = CALCULATE(DIVIDE([总销售],DISTINCTCOUNT(Sheet1[年月])),DATESINPERIOD('Sheet1'[日期],MAX('Sheet1'[日期]),-1,YEAR))

原理:DIVIDE([总销售],DISTINCTCOUNT(Sheet1[年月])做为Calculate的计算器,其实它本身就是度量值。

【近12个月的移动平均1】是先计算区间值总和再除12。

【近12个月的移动平均2】在计算器内进行平均值的计算,根据筛选器的月份总数筛选对哪些月份进行计算。

我们验算一下:(1+15)*15/2=120-(1+2+3)=114/12=9.5

友情提示: 【近12个月的移动平均1】在生成度量值后,它的数据类型可能是整数,因为我之前的数值都是整数类型,所以结果可能是10,需要修改数据类型为十进制数字,保留小数点后2位。然而近12个月的移动平均2就不会有这个问题,因为在做安全除法时,必然会出现小数点,数据类型已经自动改变。

《孙兴华讲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等等

https://www.bilibili.com/read/cv10222110 

Power BI之DAX神功:答网友问10 计算移动总计必先理解日期区间的评论 (共 条)

分享到微博请遵守国家法律