Power BI基于DAX实现动态ABC分析的分类单独筛选问题
问题场景
需要按客户、商品、销售人员等维度开展收入ABC分析,已完成客户维度的收入A/B/C分层逻辑搭建,但单独筛选A、B、C类别时运行异常:需要筛选A类客户对应的商品收入数据,在独立表格中展示A类客户关联Client_key下的商品及对应收入金额时,出现部分商品遗漏的问题。
已知Revenue事实表包含Client_key、Item_key、Amount三个字段。
原有实现及问题点
- 目标商品收入度量值(运行异常)
_Key_Measures[NeededRevenue] = SUMX( FILTER( SUMMARIZE( Revenue, Revenue[Client_Key], Revenue[Item_Key], "Cat", _Key_Measures[ClientABC], "Rev", [TotalRev] ), [Cat] = "A" ), [Rev] )
异常表现:上述表达式中
SUMMARIZE部分无法正确汇总Client_key与Item_key的组合,存在部分Item_key遗漏;移除"Cat", _Key_Measures[ClientABC]参数后,汇总功能恢复正常。
- 依赖的关联度量值
- 客户ABC分类规则
_Key_Measure[ClientABC] = IF( [ClientRevC%] <= 0.7, "A", IF([ClientRevC%] <= 0.9, "B", "C") )
- 客户累计收入占比计算
ClientRevC% = VAR CurrentTotal = SUM(Revenue[Amount]) VAR TotalRev = CALCULATE([TotalRev], ALLSELECTED(Revenue)) VAR CumTotal = SUMX( FILTER( SUMMARIZE( ALLSELECTED(Revenue), Clients[Client], "Revenue Total", SUM(Revenue[Amount]) ), [Revenue Total] >= CurrentTotal ), [Revenue Total] ) RETURN DIVIDE(CumTotal, TotalRev, 0)
- 总收入基础度量值
TotalRev = SUM(Revenue[Amount])
问题根因
SUMMARIZE函数在嵌套调用依赖上下文转换的度量值时,会受当前行所有分组维度的筛选影响。在SUMMARIZE中同时按Client_key和Item_key分组时计算ClientABC,此时分类计算的上下文是「客户+商品」的细粒度组合,不是纯客户维度,导致分类结果不符合预期,部分商品组合被错误过滤,最终出现Item遗漏。
修正方案
不要在多维度分组的SUMMARIZE内部直接计算客户维度的ABC分类,先单独在客户粒度完成分类计算,再将分类结果作为筛选条件应用到商品维度的收入计算中。
修正后的NeededRevenue度量值如下:
_Key_Measures[NeededRevenue] = // 第一步:单独在客户维度计算ABC分类,不受商品维度筛选干扰 VAR ClientWithABC = ADDCOLUMNS( VALUES(Clients[Client_key]), "ClientClass", [ClientABC] ) // 第二步:提取所有A类客户的Client_key列表 VAR AClassClients = SELECTCOLUMNS( FILTER(ClientWithABC, [ClientClass] = "A"), "A_Client", Clients[Client_key] ) // 第三步:仅保留A类客户的筛选上下文,计算对应商品收入 RETURN CALCULATE( [TotalRev], TREATAS(AClassClients, Revenue[Client_key]) )
如果数据模型中Clients维度表和Revenue事实表已经建立了标准的一对多关系,可以用更简洁的写法:
_Key_Measures[NeededRevenue] = CALCULATE( [TotalRev], FILTER(ALL(Clients[Client_key]), [ClientABC] = "A") )
使用时将Item_key放入表格行字段,挂载上述度量值即可正常展示所有A类客户对应的商品及收入,不会出现商品遗漏问题。如果需要切换B、C类筛选,只需要修改过滤条件中的分类值即可,同一套逻辑也可以复用到销售人员、商品等其他维度的ABC分析场景。
内容的提问来源于stack exchange,提问作者Tania

