Power BI之DAX神功:第2卷第14回 半累加计算就是日期维度最大日期对应的值
一、理解半累加计算

假设:我是卖西瓜的,每天都有进货和销售,每天也会剩下一些瓜。
Sheet1这张表是我以每月第1天与最后一天为例,中间日期省略
1月份我剩余西瓜的数量,应该是2
第1季度剩余瓜的数量,应该是6
总之,日期维度中最后一天的库存就是我的结余库存。
神仙们给它起了一个名字:半累加计算
从来就没有什么救世主,也不靠神仙皇帝!
要创造人类的幸福,全靠我们自己!
来源于《国际歌》
我们将Sheet1的字段放到矩阵上:

这样做结果全是错的,它是将日期维度的值求和了,如果是计算销售数量或金额那是正确的
现在我们只需要每个维度最后一个日期的值。
二、LastDate函数
返回日期列的最大日期(只有一行一列的表)
这里的日期列,也可以是另一个时间智能函数生成的只有日期列的表。
详见《DAX神功》答网友问08 嵌套使用时间智能函数
【新建表】表 = LASTDATE('Sheet1'[日期])

【度量值】总库存 = sum(Sheet1[库存])
【度量值】最后一天的库存 = CALCULATE([总库存],LASTDATE('Sheet1'[日期]))

正常人其实都是这样写的,什么情况下是不正常呢?
例如:起床不洗漱,做饭不洗菜,吃饭不洗手.....
现实中,很多做数据分析的人有类似上述行为,但他并不是高手,他处处遇坑,爬起来继续摔。他们信仰:“酒肉穿肠过 ,佛祖心中留, 世人若学我,如同进魔道。” 出自《济公李修缘》
电视剧中的济公也不洗手,但他不会得病,你学他,你可能会住院。世人对济公的话只听前半句,不听后半句。所以他们研究复杂的DAX原理,而不进行数据清洗。
三、世人若学他,原理走一波
我们将Sheet1表2021/1/31的库存清空,现实中这一天我忘记盘点了,那么他应该取2021/1/31最近的一个日期,在我们表上是2021/1/1的库存值。

遇到这张表的情况,有1月份的最大日期,但是最大日期对应的值为空。
【度量值】总库存 = sum(Sheet2[库存])
【度量值】最后一天的库存 = CALCULATE([总库存],LASTDATE('Sheet2'[日期]))
结果就变成了下面这样:

如果你将表导入PowerBI时先到PowerQuery中数据清洗过滤掉库存为空的行,就没有下面的问题了。
如果你没有洗菜,你炒菜时,发现菜里面有一个蜗牛或者有一只蚯蚓。
解决办法是什么:把它们捡出来扔掉。否则就是洗菜。
你不洗,你研究原理,那么我们就讲讲把蜗牛和蚯蚓扔掉的方法。
Ps: 方法并不唯一!
【新建表】表 = FILTER('Sheet2','Sheet2'[库存]<>BLANK())

建立虚线关系
详见《DAX神功第1卷第21回》Calculate调节器USERELATIONSHIP函数

【度量值】非空最后一天库存 = CALCULATE([总库存],LASTDATE('表'[日期]),USERELATIONSHIP('Sheet2'[日期],'表'[日期]))

友情提示:其实真的没有这么麻烦,因为你们还没有学习数据沿袭,《DAX神功》第2卷第22回学完以后,你就可以使用数据沿袭的方法来解决这个问题
四、当你使用日期表时,会有另一种情况
我将2021/1/31日删除,得到下面这张表:2021/1/1我盘点时发现了还有1个西瓜,后来我又发现被刘华强劈了一个瓜,瓜还在,明天打上保鲜膜接着卖成西瓜切:)所以2021/1/1西瓜共2个库存

第一步:创建日期表
日期表 = ADDCOLUMNS(
CALENDAR(FIRSTDATE('Sheet1'[日期]),LASTDATE('Sheet1'[日期])),
"年", YEAR ( [Date] ),
"季度", ROUNDUP(MONTH([Date])/3,0),
"月", MONTH([Date]),
"周", weeknum([Date]),
"年季度", year([date]) & "Q" & ROUNDUP(MONTH([Date])/3,0),
"年月", year([Date]) * 100 + MONTH([Date]),
"年周", year([Date]) * 100 + weeknum([Date]),
"星期几", WEEKDAY([Date])
)
大家应该知道,日期表产生的是2021/1/1~2021/10/31连续日期的数据
第二步:建立关系

第三步:写度量值
【度量值】总库存 = sum(Sheet1[库存])
【度量值】最后一天的库存 = CALCULATE([总库存],LASTDATE('日期表'[Date]))

出现这个问题的原因:日期表中1月的最大日期是2021/1/31,因为我们使用的LASTDATE('日期表'[Date])。但是2021/1/31并没有库存,所以这里显示为空。
解决方案:
===《The Definitive Guide to DAX》中建议写法===
【度量值】书中方案 = CALCULATE([总库存],LASTNONBLANK('日期表'[Date],COUNTROWS(RELATEDTABLE(Sheet1))))
原理:LASTNONBLANK扫描第1参数那个表的日期列,并返回第2参数不为空时所对应表的最后一个值。
===我的方案===
【度量值】我的方案 = CALCULATE([总库存],LASTDATE('Sheet1'[日期]))
原理:找到Sheet1表日期列的日期维度最大值

五、换成多商品的表格

我们仍然使用刚才的度量值


所以,《The Definitive Guide to DAX》关于本节最后两个度量值,我是用不到的,您可以做为学习研究,我可以用上述方式实现,就没必要使用复杂方式处理了。

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