深入浅出DAX:购买推荐及产品ABC分类分析
DAX运算求值的三步骤。首先是检测筛选,然后将筛选功能应用于基础表格,最后计算结果。DAX中的筛选器函数是复杂且功能强大的函数。例如筛选函数可用于操作数据上下文来创建动态计算。
01、使用细节说明
在DAX中,NOT用于求反操作,IN用于或操作,但不能像SQL中直接NOT IN直接紧邻操作。以下是DAX中在IN 语句之前使用 NOT的应用举例,表达式如下:
M.其他收货人:=
CALCULATE (SUM ( '运单'[数量] ),NOT ('收货'[收货人] IN VALUES ( '收货'[收货人]))
)
返回的值如图1所示。
■ 图1 NOT与IN的结合应用
IN后面是允许连接两列或多列,其中列表用{}构造,而每行的数据则用括号()构造,其中的括号()代表的是元组,元组内包含的是每行的数据,元组内的数据用逗号区隔。应用举例:
('装货'[包装方式], '装货'[产品]) IN {("桶装","尿素"),("箱装","蛋糕纸")}
以上表达式同样可以置于CALCULATE()函数中参与筛选应用的。
在DAX中使用迭代函数时,必须注意到第1个参数的表是来自数据模型的一端还是多端,避免因迭代类聚合函数忽略行上下文而产生的总计值错误。应用举例,创建度量值M.总成本1和M.总成本2,表达式如下:
M.总成本1:= SUMX('合同',
SUMX('运单','运单'[成本]*'运单'[数量]))//该表达式返回的总计值有误M.总成本2 := SUMX('合同',
CALCULATE(
SUMX('运单','运单'[数量]*'运单'[成本])))
创建透视表,将合同表的产品拖入行标签,勾选度量值M.总成本1和M.总成本2,返回的值如图2所示。
■ 图2 在模型的一端运用聚合函数
02、购买与推荐分析
CALCULATE()函数的第1个参数返回的结果为值,常用于COUNTROWS()、SUM()等聚合函数;第1个参数会依据紧接其后的各筛选器参数所修改的上下文来计算,第2个参数可以为表。表达式如下:
M.共有产品 :=
CALCULATE (SUM('订单'[数量]),INTERSECT (VALUES ( '订单'[产品] ),VALUES ( '运单'[产品] ))
)
除第1个参数外,其他参数均为表。应用举例,表达式如下:
M.共有产品B :=
CALCULATE (SUM('运单'[数量]),INTERSECT (VALUES ( '订单'[产品] ),VALUES ( '运单'[产品] )),INTERSECT (VALUES ( '装货'[包装方式] ),VALUES ( '运单'[包装方式] ))
)
订单表中共11个产品(数量和205);在运单表中共10个产品(没有的产品为包装绳,数量为2)。返回的值如图3所示。
在CALCULATE()的第2个参数中,利用FILTER()参数部分扩大或缩小筛选上下文的范围。表达式如下:
M.度量ZF:=
CALCULATE (DISTINCTCOUNT ( '运单'[运单编号] ),FILTER (ADDCOLUMNS (
VALUES ( '运单'[运单编号] ),
"行数", COUNTROWS ( '运单' )
),[行数] > 0)
)
返回的值如图4所示。
■ 图4 CALCULATE()中的FILTER()参数
03、产品ABC分类分析
在DAX中ABC分类分析一般通过三步来完成的。第1步:利用计算列或度量值计算累计值;第2步:依据累计值完成累计占比;第3步:对占比进行ABC分类。创建度量值M.运单量、M.累计运单量、M.累计占比、M.ABC分类。表达式如下:
M.运单量:=SUM('运单'[数量])M.累计运单量 :=
VAR A = [M.运单量]
VAR B =ADDCOLUMNS ( ALL ( '运单'[产品] ), "运量", [M.运单量] )
RETURNIF (HASONEVALUE ( '运单'[产品] ),SUMX ( FILTER ( B, [运量] >= A ), [运量] ))M.累计占比 :=
DIVIDE ([M.累计运单量],CALCULATE ( [M.运单量], ALL ( '运单'[产品] ) )
)M.ABC分类 :=
IF (HASONEVALUE ( '运单'[产品] ),SWITCH (TRUE (),[M.累计占比] <= 0.7, "A",[M.累计占比] <= 0.9, "B","C")
)
创建透视表,将运单表中的产品拖入行区域,勾选度量值M.运单量、M.累计运单量、M.累计占比、M.ABC分类。返回的值如图5所示。
■ 图5 产品的ABC分类分析
04、产品期初与结存分析
在DK表中,创建计算列库.年月,表达式如下:
库.年月:= YEAR('DK'[日期])*100+MONTH('DK'[日期])
结存分析的基本原理:上期的期末等于本期的期初。创建度量值M.入库量、M.出库量、M.期初量、M.结存量,表达式如下:
M.入库量:= SUM(DK[入库])
M.出库量:= SUM(DK[出库])M.期初量:=
CALCULATE ([M.入库量] - [M.出库量],FILTER (ALL ('DK'[库.年月] ),'DK'[库.年月] < MIN ( 'DK'[库.年月] ))
)M.结存量:= [M.期初量]+[M.入库量]-[M.出库量]
创建透视表,将库.年月拖入行标签,勾选度量值M.期初量、M.入库量、M.出库量、M.结存量。返回的值如图6所示。
■ 图6 出入库期初与结存分析