Power BI非标准日历的计算思路
对于按照自然年月日来分析的业务数据,在PowerBI中可以轻松的使用时间智能函数来进行各种时间指标的计算,但如果不是按标准的日历,很多人就开始有点懵,不知道该如何计算了。
比如有的公司的业务月份是从26号到下个月的25号,如何计算本月收入和上月收入呢?
这种还比较简单,虽然不是标准的日历,其实还是很日历相关的,只是错位了几天而已,可以构建一个业务日历表,然后还是可以用时间智能函数来计算。
考虑个更加不标准的业务日历,假如某公司是按25天为一个业务周期,这种情况下,完全和自然的年月没有关系,时间智能函数无法使用,如何计算本期、上期、环比等指标呢?
这篇文章就来给你一个普遍意义上的时间指标计算思路。
以业务周期25天为例,首先根据业务的周期,在日期表中添加业务周期的字段,如下图,
添加了两个字段,其中一个是文本的期间P1、P2等,便于阅读,另外一个是数值的期数1、2……,便于排序以及不同期间的逻辑运算。
依然用这个表的日期与业务数据表的订单日期建立关系,
先写一个基础度量值:
收入 = SUM('订单表'[销售额])
下面就用度量值来计算几个常用的时间指标。
上期
收入 上期 = VAR _period=SELECTEDVALUE('日期表'[期数]) RETURN CALCULATE( [收入], FILTER( ALL('日期表'), '日期表'[期数]=_period-1 ) )
这个度量值的逻辑是,先利用VAR找到当前上下文的期数,然后在日期表中,找出比当前期数少一期的日期,并用这些日期筛选订单表中的对应订单日期的业务,求和即为上一期的收入。
这里用到的函数组合:
VAR+CALCULATE+FILTER+ALL
它是非常经典的DAX套路,在很多场合都会用到,即使还不理解也要先记住它,建议你重复练习直至彻底掌握。
有了上期数据,计算同比就很简单了,
同比 = DIVIDE([收入]-[收入 上年同期],[收入 上年同期])
结果如下:
同理还可以计算上年同期,不过这里假设的是25天一个业务月度周期,并没有上年的概念,不如再假设一个业务年度,仍然以12期为一年,那么上年同期就可以这么计算。
上年同期
收入 上年同期 = VAR _period=SELECTEDVALUE('日期表'[期数]) RETURN CALCULATE( [收入], FILTER( ALL('日期表'), '日期表'[期数]=_period-12 ) )
自然日历的计算不是同样如此吗,上月是本月之前1个月的月份,而上年同期就是本月往前推12个月的月份。
同比 = DIVIDE([收入]-[收入 上年同期],[收入 上年同期])
结果如下:
看以上几个度量值,好像没有用到日期,只用到期数,这是因为上面的计算粒度都是按"期"计算,并没有按"日"计算。
假设计算本期至今的数据,应该怎么写呢?
本期至今
收入 本期至今 =
VAR _period=SELECTEDVALUE('日期表'[期数])
VAR _date=MAX('日期表'[日期])
RETURN
CALCULATE(
[收入],
FILTER(
ALL('日期表'),
'日期表'[期数]=_period
&&'日期表'[日期]<=_date
)
)
本期至今的逻辑就是期数和当前上下文的期数相等,但小于等于当前日期的订单销售额之和。
所以用了两个变量来分别获取当前上下文的期数和日期。
结果如下:
通过上面几个时间指标的计算,你是不是已经知道非标准日期的计算逻辑了呢,其实这才是最普遍意义上的时间指标计算,就是根据业务的逻辑,按条件筛选汇总而已。
时间智能函数内部也是这样的逻辑,比如本月至今,有个时间智能函数是DATESMTD,它内部的运行逻辑依然是:
收入 本月至今 =
VAR _month=SELECTEDVALUE('日期表'[月份])
VAR _date=MAX('日期表'[日期])
RETURN
CALCULATE(
[收入],
FILTER(
ALL('日期表'),
'日期表'[月份]=_month
&&'日期表'[日期]<=_date
)
)
这个度量值和上面的本期至今,除了把 [期数] 替换为 [月份] ,其他完全一致;等于当前月份,但小于等于当前日期的数据之和不就是本月至今吗?
把常用时间维度的业务计逻辑进行封装,就形成了时间智能函数,大家平时只知道用,因为很方便,只要能计算出结果,就不去深入理解时间智能函数到底是如何工作的,这导致了实际业务中,日历稍微一变化,就不知道怎么计算了。
如果彻底理解了这些计算逻辑,并学会利用本文的DAX思路,再碰到各种奇葩日历的时间指标计算,都可以迎刃而解。
其实之前写过的按周分析的思路,同样的计算逻辑: