DAX/PowerBI系列 - 父子層級(Parent-Child Hierarchy)
難度: ★★☆☆☆(2星)
適用范圍: ★★★☆☆(3星)
應用場景:
其實很多時候對數據匯總都會有層級關系的問題,不過這個模式說的不是產品分類--子分類這樣的場景,而說的是父和子都是存到同一個表中(通過一個父節點的字段指定parent),而且父節點和子節點也可能會產生業務數據。
以下是幾個應用場景:
- 銷售 - 組織架構層級
- 銷售員A賣產品,ta的下線a1,a2,a3也銷售產品,如何統計ta和ta的下線一個賣了多少產品。
- 成本 - 產品和產品組件
- 產品A有一個組裝成本,產品組件a1,a2,a3也分別有它們的組裝成本,要對總成本匯總。
- 盈虧 - 賬戶和關聯子賬戶
- 打怪 - 大號與各個小號
歡迎交流與騷擾
Power BI顯示如下:

以銷售為例:
|
|
要點: 1.構建遍歷結構 2.判斷是否為末節點 3.定義遍歷層級 4.當計算當前元組對應的瀏覽的節點深度
注意:由於用中文來命名表/列名並用此來寫DAX比較痛苦,試了幾次都覺得不太順手,最后還是用英文了,(⊙o⊙)…
歡迎轉載,請保留原文鏈接和作者信息。O(∩_∩)O謝謝。 DAX/PowerBI系列 - 父子層級(Parent-Child Hierarchy) 作者:馬丁叔叔
鏈接:http://www.cnblogs.com/lizardbi/p/DAX-PATTERN-POWERBI-Parent-Child-Hierarchy.html
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里面入門級的一個了。
參考文章:http://www.daxpatterns.com/parent-child-hierarchies/
歡迎圍觀和討論。。。