深入浅出DAX:购买推荐及产品ABC分类分析-LMLPHP

深入浅出DAX:购买推荐及产品ABC分类分析

DAX运算求值的三步骤。首先是检测筛选,然后将筛选功能应用于基础表格,最后计算结果。DAX中的筛选器函数是复杂且功能强大的函数。例如筛选函数可用于操作数据上下文来创建动态计算。

01、使用细节说明

在DAX中,NOT用于求反操作,IN用于或操作,但不能像SQL中直接NOT IN直接紧邻操作。以下是DAX中在IN 语句之前使用 NOT的应用举例,表达式如下:

M.其他收货人:=
CALCULATE (
    SUM ( '运单'[数量] ),
    NOT (
        '收货'[收货人] IN VALUES ( '收货'[收货人])
   )
)

 返回的值如图1所示。

深入浅出DAX:购买推荐及产品ABC分类分析-LMLPHP

■ 图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所示。

深入浅出DAX:购买推荐及产品ABC分类分析-LMLPHP

■ 图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所示。

深入浅出DAX:购买推荐及产品ABC分类分析-LMLPHP

 在CALCULATE()的第2个参数中,利用FILTER()参数部分扩大或缩小筛选上下文的范围。表达式如下:

M.度量ZF:=
CALCULATE (
    DISTINCTCOUNT ( '运单'[运单编号] ),
    FILTER (
        ADDCOLUMNS (
VALUES ( '运单'[运单编号] ),
"行数", COUNTROWS ( '运单' )
),
        [行数] > 0
    )
)

 返回的值如图4所示。

深入浅出DAX:购买推荐及产品ABC分类分析-LMLPHP

■ 图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.运单量] )
RETURN
    IF (
        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所示。

深入浅出DAX:购买推荐及产品ABC分类分析-LMLPHP

■ 图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所示。

深入浅出DAX:购买推荐及产品ABC分类分析-LMLPHP

 ■ 图6 出入库期初与结存分析

10-09 15:37