DAX从入门到精通 6-2 计算累计值

另一个常用的计算,是计算累计值。累计值,也就是当我们有一些列的顺序的数值,然后对其按照顺序进行累积,通常是按照时间顺序。例如,我们可能会需要按照时间计算总销售额,计算累计销量,或者按照时间计算累积的客户数。

我们看下面这个案例,我们现在又每个时间段的销售量:


image.png

这个度量值的计算很简单如下:

[NumOfProducts] := SUM ( Sales[Quantity] )

可以知道,这个度量值在现有上下文的情况下,计算销售数量。例如,我们看2007年5月,这时候筛选上下文就是2007年,月份是5月。然后过滤器作用于日期,因为日期是处于和销售表sales关系的一方,所以,筛选条件会传导到sales表中,只显示2007年5月的值。

如果你要计算累计值,我们就必须要找一个新的筛选上下文,而不是使用2007年5月这个。新的过滤条件是2007年5月底之前的所有时间。看起来很简单,但是实际上比较复杂。我们要这样做:
1.确定当前日期的最后一天,例子中的就是2007年5月。
2.使用这个值,建立一个筛选上下文,过滤出小于这个值的所有日期。

这个复杂性 来源于新的筛选上下文要依赖于现有的。进一步也就是,新的筛选上下文的范围会比现在的大,因为它要包含的是当前和之前的日期。下图中,我们可以看到,要提取的时间范围。

image.png

带着我们解决问题的思路,我们来看下解决这个问题的函数:

[CumulativeProducts] :=
CALCULATE (
SUM ( Sales[Quantity] ),
FILTER (
ALL ( 'Date' ),
'Date'[Datekey] <= MAX ( 'Date'[Datekey] )
))

这个函数的重点是我们用calculate新建的筛选条件。我们把注意力放到这个表达式的两个关键点上。

我们使用了all(date)目的是忽略现有的日期筛选条件。这里,filter会迭代整个日期表,这个范围比现有的条件要大。这样,它就具备返回小于等于当前筛选上下文条件的日期。这个功能也可以用于日期表的其他列,比如weeks,quarter等。

date[datekey]和max(date[datekey])对比。如果你对DAX不熟悉,那么这个表达式看起来就有点奇怪。但是,如果你回顾下MAX的含义,其解释为“当前上下文情况下datekey的最大值”。因为这个表达式是calculate筛选条件的一部分,所以它依旧会在原先的上下文环境下工作,也就是2007年5月。因此,最大日期就是2007年5月底。另外一方面,date[datekey]是列的名称,也就是该列在当前行上下文环境下的值。因为行上下文是在filter迭代中产生的,所以表达式的意思就是小于等于2007年5月最后一天的所有日期。

可以看到,函数起了作用,如下图:

image.png

虽然这个函数计算的值是正确的,它按照时间顺序累加了。不过,在2010年后,我们看到是空的,也就是还没有销量,数据显示了未来一段时间的情况。这个逻辑上是正确的,数字上也是对的。但是,你可能想只显示有值的部分,把空的隐藏起来。

你可以使用空blank把这些不需要的行给替换了。事实上,按你现在所学的,透视表会默认的把空行或者空列自动隐藏。要达到这个目的,很简单使用if函数就可以,if检测当前行,如果空,就设置为blank()。

[CumulativeProducts] :=
IF (
COUNTROWS ( Sales ) > 0,
CALCULATE (
SUM ( Sales[Quantity] ),
FILTER (
ALL ( 'Date' ),
'Date'[Datekey] <= MAX ( 'Date'[Datekey] )
)))

这个度量值中,我们if的false部分会返回blank。后面的第七章时间智能函数,我们会进一步学习能得到同样结果的函数。这里,我们作为学习目的,是要熟悉下如果在不同上下文环境下计算。

你可能感兴趣的:(DAX从入门到精通 6-2 计算累计值)