DAX-PowerBI系列

DAX/PowerBI系列 - 父子层级(Parent-Child Hierarchy)

难度: ★★☆☆☆(2星)

应用场景:

其实很多时候对数据汇总都会有层级关系的问题,不过说的不是产品分类--子分类这样的场景,而说的是父和子都是存到同一个表中(通过一个父节点的字段指定parent),而且父节点和子节点也可能会有Fact数据。

以下是几个应用场景:

  • 销售 - 组织架构层级
    •   销售员A卖产品,ta的下线a1,a2,a3也销售产品,如何统计ta和ta的下线一个卖了多少产品。
  • 成本 - 产品和产品组件
    •   产品A有一个组装成本,产品组件a1,a2,a3也分别有它们的组装成本,要对总成本汇总。
  • 盈亏 - 账户和关联子账户
  • 打怪 - 大号与各个小号

 

以销售为例:

 

 

要点:

1.构建遍历结构
2.判断是否为末节点
3.定义遍历层级
4.当计算当前元组对应的浏览的节点深度

  

注意:由于用中文来命名表/列名并用此来写DAX比较痛苦,试了几次都觉得不太顺手,最后还是用英文了,(⊙o⊙)…

 

 1. 构建遍历机构 - 用PATH语句拿到各个人的上线

[Path] = PATH ( Nodes[Name], Nodes[Parent] )

 

 

2. 判断末节点

 先来看看那些是末节点:

[IsLeaf] =
CALCULATE (
    COUNTROWS ( Nodes ), 
    ALL ( Nodes ), 
    Nodes[ParentKey] = EARLIER ( Nodes[NodeKey] )
) = 0

 

3. 构建遍历层级

看看几层都有谁:

[HierarchyDepth] = PATHLENGTH ( Nodes[HierarchyPath] )
 
[Level1] = 
LOOKUPVALUE (
    Nodes[Name], 
    Nodes[NodeKey], 
    PATHITEM ( Nodes[HierarchyPath], 1, INTEGER )
)
 
[Level2] = 
IF (
    Nodes[HierarchyDepth] >= 2, 
    LOOKUPVALUE (
        Nodes[Name], 
        Nodes[NodeKey], 
        PATHITEM ( Nodes[HierarchyPath], 2, INTEGER )
    ), 
    Nodes[Level1] 
)
 
[Level3] = 
IF (
    Nodes[HierarchyDepth] >= 3, 
    LOOKUPVALUE (
        Nodes[Name], 
        Nodes[NodeKey], 
        PATHITEM ( Nodes[HierarchyPath], 3, INTEGER )
    ), 
    Nodes[Level2] 
)

 

 4.计算当前元组对应的浏览的节点深度,用于计算

BrowseDepth = ISFILTERED ( Nodes[Level1] )
                       + ISFILTERED ( Nodes[Level2] )
                       + ISFILTERED ( Nodes[Level3] )
 

 

假如简单的计算,

[Sales Amount Simple] :=
IF (
    [BrowseDepth] > [MaxNodeDepth],
    BLANK (),
    SUM ( Transactions[Amount] )
)

 

 

 

问题:

 你会发现:上面有图并没有显示Brad和Annabel各自的值[Sales Amount Simple],但是他们现在汇总的值却比他们对应的子节点的总和要大。

譬如:Brad子节点汇总应该为(Chris400 + Vince500 = 900),但是Brad却为1300。而Brad本身400并没有显示出来。

改进:

[Sales Amount] :=
IF (
    [BrowseDepth] > [MaxNodeDepth] + 1,
    BLANK (),
    IF (
        [BrowseDepth] = [MaxNodeDepth] + 1,
        IF (
            AND (
                VALUES ( Nodes[IsLeaf] ) = FALSE,
                SUM ( Transactions[Amount] ) <> 0
            ),
            SUM ( Transactions[Amount] ),
            BLANK ()
        ),
        SUM ( Transactions[Amount] )
    )
)

 

 

上面为原文给出的计算,可以看到 左图为pivot table勾选了显示没有数据的显示,右图为不显示没有数值的行。注意这里要显示Subtotal才会显示中间的节点和根节点,如果不勾选的话就会得到下图。

 

 

正如下面左边,在PowerBI里面,并没有正确的显示。

 

再改进:

Sales $ = 
    IF (
        [BrowseDepth] > [MaxNodeDepth] + 1 ,
        IF (
            AND ( 
                VALUES ( Nodes[IsLeaf] ) = FALSE,
                SUM(Transactions[Amount]) <> 0
            ),
            SUM(Transactions[Amount]),
            BLANK ()
        ),
        SUM(Transactions[Amount])
    )

Excel显示如下:左边为隐藏没有数据的行,右边显示了没有数据的Bill

PowerBI显示如下:

左边是上面改进前的[Sales Amount]的显示,右图是上面[Sales $]的显示。最后一列才是我想要的。

右上的图可以drill-down,如果想玩,可以在这里下载。链接: https://pan.baidu.com/s/1geJe3yN 密码: hfh7

 

 

 好了,这算是在DAX patterns里面入门级的一个了。

PowerBI文件戳这里下载:链接: https://pan.baidu.com/s/1geJe3yN 密码: hfh7 

Excel文件:链接: https://pan.baidu.com/s/1qYLKlHU 密码: 6uyr

 

参考文章:http://www.daxpatterns.com/parent-child-hierarchies/ 

 

 欢迎围观和讨论。。。

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值