问题

在使用PowerBI制作月度活跃店铺统计时遇到一个问题,需要根据基于切片器选项的动态时间产生月度扫码量总和。

解决思路

1.直接求和并用CALCULATE筛选

一开始考虑直接写总量、然后用CALCULATE函数加上时间条件筛选:

期间内扫码量 = CALCULATE(
	DISTINCTCOUNT('whitelist retail_code'[ter_num]),
	CALCULATE(
		SUM('whitelist retail_code'[average]),
		'whitelist retail_code'[date]>=MIN('calendar'[Date]),
		'whitelist retail_code'[date]<=MAX('calendar'[Date])
	)>SELECTEDVALUE('choosen'[choosen])
)

于是报错:

函数“PLACEHOLDER”已用于一个 True/False 布尔表达式,该表达式用作表筛选表达式。这是不允许的。

原来是CALCULATE函数不接受将其它CALCULATE函数作为自己的筛选条件,CALCULATE函数本身相当于创建了一个独立的上下文环境。(区别于FILTER的筛选,FILTERCALCULATE不会产生冲突,但在这个案例里不好用)

2.创建辅助表来聚合数据

于是想到,是不是可以创建一个辅助表,直接聚合得到各店铺的月度数据?于是编写聚合表:

distinct = SUMMARIZE(
	FILTER(
            [ter_num],
			[date],
            "total",SUM('whitelist retail_code'[average]),
        )

聚合表的好处是确实产生了可以直接被调用的正确数据,但产生一个新的问题,无法按照切片器的选择动态的切换显示的时间跨度。譬如,当前要求按月分析扫码量,但如果未来业务变化,需要精确到周乃至日,需要重新修改报表底层,很不划算。

3.在度量值中创建动态表

最后选择直接在度量值中编写动态表,因为不直观(度量值不能直接输出表)走了好多弯路……最终编写的度量值:

是活跃店 = CALCULATE(
    SUMX(
        SUMMARIZE(
            FILTER(
				'whitelist retail_code',
				AND([date]>MIN('calendar'[Date]),[date]<=MAX('calendar'[Date]))
			),
            [ter_num],
            "total",
			SUM('whitelist retail_code'[average]),
            "acticve",
			IF(
				SUM('whitelist retail_code'[average])>=SELECTEDVALUE(choosen[choosen])
				,1
				,0
			)
        ),[acticve])
    )

利用SUMMARIZE创建了一个基于时间函数表calendar的动态聚合表,将扫码箱数总和记录在[total]列中,并通过[active]列标记其是否是活跃店(我们认为如果他的扫码箱数超过了我们设定的[choosen]值,他就是活跃店)。

这里用了一个投机取巧的办法,直接把是活跃店的店铺设为1,这样利用SUMX就能直接计算出活跃店总数(同时也很便于修改成统计非活跃店的度量值)。

还有什么问题吗?

由于[是活跃店]本质上是一个总和,这个度量值无法直接使用PowerBI自带的高级筛选器和其它需要更细粒度的功能。留着后面解决吧。