PowerBI DAX 在矩阵分组区域内通用积累求和

2020-09-28 11:08:39 浏览数 (1)

什么是在矩阵分组区域内积累求和,先看一个例子吧。

对于左右两个图表,它们的规律是:

  • 左图:在分组区域内,按照与当前元素的KPI从小到大,积累求和;
  • 右图:在分组区域内,按照与当前元素的名称从小到大,积累求和。

这两种模式都非常常见,很多计算都会涉及这个问题。

这里给出了两种实现,一种是模型层计算;一种是视图层计算。

分别进行详解。我们先给出计算公式,再对重要技巧做出总结。

按KPI积累,模型层计算

DAX 公式如下:

代码语言:javascript复制
KPI.组内积累.按KPI大小.模型法 =
VAR _value = [KPI]
VAR _items =
    FILTER(
        CALCULATETABLE( SUMMARIZE( Customer , Customer[Industry] , Customer[Occupation] ) , ALL( Customer[Occupation] ) ),
        [KPI] <= _value
    )
RETURN CALCULATE( [KPI] , _items )

按KPI积累,视图层计算

DAX 公式如下:

代码语言:javascript复制
KPI.组内积累.按KPI大小.视图法 =
VAR _value_current = [KPI]
VAR _view =
CALCULATETABLE(
    ADDCOLUMNS(
        SUMMARIZE( Customer , Customer[Industry] , Customer[Occupation] ),
        "@KPI",
        [KPI]
    ),
    ALLSELECTED( )
)

VAR _group = VALUES( Customer[Industry] )

RETURN 
    SUMX( _group ,
        SUMX( _view , IF( [Industry] = EARLIER( Customer[Industry] ) && [@KPI] <= _value_current , [@KPI] ) )
    )

按名称积累,模型层计算

DAX 公式如下:

代码语言:javascript复制
KPI.组内积累.按元素名称.模型法 =
VAR _value = [KPI]
VAR _item  = SELECTEDVALUE( Customer[Occupation] , "座座座座" )
VAR _items =
    FILTER(
        CALCULATETABLE( SUMMARIZE( Customer , Customer[Industry] , Customer[Occupation] ) , ALL( Customer[Occupation] ) ),
        ISONORAFTER( [Occupation] , _item , DESC )
    )
RETURN CALCULATE( [KPI] , _items )

按名称积累,视图层计算

DAX 公式如下:

代码语言:javascript复制
KPI.组内积累.按元素名称.视图法 =
VAR _value_current = SELECTEDVALUE( Customer[Occupation] , "座座座座" )
VAR _view =
CALCULATETABLE(
    ADDCOLUMNS(
        SUMMARIZE( Customer , Customer[Industry] , Customer[Occupation] ),
        "@KPI",
        [KPI]
    ),
    ALLSELECTED( )
)

VAR _group = VALUES( Customer[Industry] )

RETURN
    SUMX( _group ,
        SUMX( _view , IF( [Industry] = EARLIER( Customer[Industry] ) && [Occupation] <= _value_current , [@KPI] ) )
    )

总结

我们在此前多次提到视图层计算,其通用思维模式其实已经给出,真正的正式给出也呼之欲出,我们会单独发文。

反思

首先,这个问题,让我们对 DAX 计算再次反思:

DAX 计算从本质来讲,永远发生在模型层。

但若对于某计算,其计算若只需依赖已经计算完毕的内容,我们称:

1、已经计算完毕的内容为视图;

2、基于视图再进行的二次计算为视图层计算。

请大家仔细观察上述两种模式的实际 DAX 公式,便可以发现视图层计算往往具有两大重大优势:

1、已经计算完毕的内容由于往往可以得到缓存而使得后续计算更快;

2、已经计算完毕的内容不会再收到筛选上下文等复杂逻辑影响,更容易编写后续计算逻辑。

这便是对 DAX 计算的反思。

微软 PowerBI 产品组正在面临一个非常尴尬的抉择问题:

1、若 PowerBI 提供原生的视图层计算功能,如:一个新的函数集合,但不属于 DAX,那么,这将使得 PowerBI 除了有 Power Query 的 M,以及数据建模 DAX,又将出现一个视图计算的新函数库,导致 PowerBI 会变得更加难以理解,这是不希望发生的。

2、若 PowerBI 将视图层计算功能融入到 DAX 中,将导致作为纯模型层计算的函数库 DAX 掺杂了其他内容而使得 DAX 不再纯粹,这也是不希望发生的。

因此,在微软 PowerBI 产品组决定使用任何方法之前,都会意识到不管怎么决定,对 PowerBI 都将引入新的复杂性。

本案例技巧

本案例在计算按名称累计时,使用了一个非常有创意的技巧:SELECTEDVALUE( Customer[Occupation] , "座座座座" )

默认返回"座座座座",将作为中英文世界的词语几乎是最大字符而使得在小计行或总计行可以完成正确的计算。

0 人点赞