- 1 -
最近一位朋友在用Power BI做一项与日期相关的分析时,出现了一些看起来很奇怪的情况:
用DATESBETWEEN函数求上半年的销售合同金额,结果每年得到的数据除了最后的2022年外,都是全年的(紫色框部分)。
具体如下图所示:
这,到底怎么回事儿呢?(配套数据下载链接见文末)
经过仔细观察,发现这个DAX公式里有个很特别的地方,就是对日期使用了.[Date]的日期引用形式:
可能比较多朋友在写DAX公式,引用日期时,看到过.[Date]的情况,比如在写公式时,输完某个日期列的时候,就会自动弹出来.[Date]、.[MonthNo]……一堆选项:
此时,直接回车就会把.[Date]带入公式中,最后写成上面的公式的样子。但是,这个到底是什么?可能很多朋友就没有想过或者不清楚。
- 2 -
此前,我写过文章《开始用Power BI?别急!这几个选项配置值得注意!| PBI实战》,其中提到,要先把“自动日期”的设置取消掉,因为这个自动日期会产生很多不良的影响:
除了我在那个文章中讲的生成自动日期结构外,与本篇文章的奇怪计算结果也有密切关系!
Power BI自动日期表的原理,可以这样理解——Power BI会对于每一个日期列(包括日期表的日期),生成一个隐藏的日期表,并与这个日期列形成1对多的关系:
同时在原表中生成一个基于隐藏日期表的日期结构。如下图所示:
这个时候,在日期表里看到的两个“年”、两个“季度”、两个“月”……但他们的层次是不一样的。
基于原始日期表的日期列生成的隐藏日期表位于1端,而原始日期表位于多端,即:层次结构里的年、月等对原始日期表里的数据有筛选作用,而原始日期表里的年、月等列,对层次结构里的数据却没有筛选作用。
- 3 -
这时,我们再回头看前面的例子,矩阵中用的“年”,是原始日期表中的“年”,它并不能对生成的隐藏日期表中的数据进行筛选,所以,它对于使用 【‘日期表’[Date].[Date]】进行计算的度量,其中的【‘日期表’[Date].[Date]】的取值范围并没有受到矩阵中“年”维度的影响:
- 在每一行(年)里,它的取值范围都是整个日期表的范围
- Min(‘日期表’[Date].[Date])就是日期表中的最小日期,取年份即都是2018;
- Max(‘日期表’[Date].[Date])就是日期表中的最大日期,取年份即都是2022;
所以,上图中的DatesBetween的筛选条件,对于每一个年份,它的范围都是2018年1月1日至2022年6月30日,这时,再叠加“年”的筛选,除2022年外,得到的都是全年的数据。
这里,假设我们将矩阵中的“年”,调整为日期结构(隐藏的日期表)中的“年”,每年的上半年金额就完全正确:
但是,这里使用DatesBetween计算其实还是不合适的,因为总计行一定会出错!
总计行的原理,就是自动删除矩阵中的分组维度的筛选作用,比如这里的“年”维度。所以,当删除了年维度的筛选作用后,无论用[Date]还是[Date].[Date],得到的结果都是从2018年1月1日至2022年6月30日的合同金额之和!
那么,正确的写法是什么呢?其实很简单,不需要时间智能函数,只需要通过月份进行筛选即可:
这个例子很值得大家认真看一下,进一步理解日期、日期表以及时间智能函数的一些原理。目前,发现很多朋友在用Excel的思路去用DAX里的这些函数,一不小心就出错了,因为,这些函数虽然长得一样,但实际上差异很大!
DAX不难,但一定要沉下心来,好好把基本的原理和基础打好,一心想着看几个函数就匆忙用到工作上,不仅几乎等同于抓虾,而且还是很容易出错的。