Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Enhance your career with this limited time 50% discount on Fabric and Power BI exams. Ends September 15. Request your voucher.

Reply
CBO2404
Helper II
Helper II

Flattening a hierarchical dimension table in powerbi powerquery

I have a hierarchical dimension table in Power BI with the columns id, parent, and child. I want to flatten this table so that for each parent I get a row with its leaf, and if it is already a leaf, then the parent is equal to the leaf. Does anyone have M code to achieve this in Power Query using AddColumn on the existing dimension table?

e.g. Table Dim_XY: 

CBO2404_0-1756115048574.png

 

parent       child
AA
AB
AC
BD
BE
CF
DG

Desired result :

parent     leaf
AG
AE
AF
BG
BE
CF
DG
EE
FF
GG
2 ACCEPTED SOLUTIONS
rohit1991
Super User
Super User

Hi @CBO2404 

Below is a working script you can adapt (replace Dim_XY with your table name):

let
   Source = Dim_XY,
   ChildrenByParent = Table.Group(Source, {"parent"}, {{"children", each _[child], type list}}),
   GetChildren = (p as any) as list =>
       let r = Table.SelectRows(ChildrenByParent, each [parent] = p)
       in  if Table.IsEmpty(r) then {} else r{0}[children],
   Parents  = List.Distinct(Source[parent]),
   Children = List.Distinct(Source[child]),
   Nodes    = List.Distinct(Parents & Children),
   LeavesFrom = (n as any) as list =>
       let kids = GetChildren(n)
       in  if List.IsEmpty(kids) then {n}
           else List.Combine(List.Transform(kids, each LeavesFrom(_))),
   Pairs =
       List.Combine(
          List.Transform(
               Nodes,
               (n) => List.Transform(List.Distinct(LeavesFrom(n)), (lf) => [parent = n, leaf = lf])
           )
       ),
   Result = Table.FromRecords(Pairs),
   Sorted = Table.Sort(Result, {{"parent", Order.Ascending}, {"leaf", Order.Ascending}})
in
   Sorted


Did it work? ✔ Give a Kudo • Mark as Solution – help others too!

View solution in original post

Thank you for your quick response. When I use the M code, I get the following error message

"Expression.Error: The name 'LeavesFrom' wasn't recognized. Make sure it's spelled correctly." asking copilot ther LeavesFrom must be like :

 

LeavesFrom = let fn = (n as any) as list => let kids = GetChildren(n) in if List.IsEmpty(kids) then {n} else List.Combine(List.Transform(kids, each @FN(_))) in fn,
 

 

View solution in original post

4 REPLIES 4
Shahid12523
Resident Rockstar
Resident Rockstar

let
Source = YourTable, // replace with your table name

GetLeaves = (p as text, tbl as table) as list =>
let
children = Table.SelectRows(tbl, each [parent] = p)[child],
result = if List.IsEmpty(children) then {p} else List.Combine(List.Transform(children, each GetLeaves(_, tbl)))
in result,

AllNodes = List.Distinct(List.Combine({Source[parent], Source[child]})),
Expanded = Table.ExpandListColumn(
Table.AddColumn(Table.FromList(AllNodes, Splitter.SplitByNothing(), {"parent"}), "leaf", each GetLeaves([parent], Source)),
"leaf"
)
in
Expanded

This will give you exactly the flattened parent → leaf mapping you showed.

Shahed Shaikh
rohit1991
Super User
Super User

Hi @CBO2404 

Below is a working script you can adapt (replace Dim_XY with your table name):

let
   Source = Dim_XY,
   ChildrenByParent = Table.Group(Source, {"parent"}, {{"children", each _[child], type list}}),
   GetChildren = (p as any) as list =>
       let r = Table.SelectRows(ChildrenByParent, each [parent] = p)
       in  if Table.IsEmpty(r) then {} else r{0}[children],
   Parents  = List.Distinct(Source[parent]),
   Children = List.Distinct(Source[child]),
   Nodes    = List.Distinct(Parents & Children),
   LeavesFrom = (n as any) as list =>
       let kids = GetChildren(n)
       in  if List.IsEmpty(kids) then {n}
           else List.Combine(List.Transform(kids, each LeavesFrom(_))),
   Pairs =
       List.Combine(
          List.Transform(
               Nodes,
               (n) => List.Transform(List.Distinct(LeavesFrom(n)), (lf) => [parent = n, leaf = lf])
           )
       ),
   Result = Table.FromRecords(Pairs),
   Sorted = Table.Sort(Result, {{"parent", Order.Ascending}, {"leaf", Order.Ascending}})
in
   Sorted


Did it work? ✔ Give a Kudo • Mark as Solution – help others too!

Thank you for your quick response. When I use the M code, I get the following error message

"Expression.Error: The name 'LeavesFrom' wasn't recognized. Make sure it's spelled correctly." asking copilot ther LeavesFrom must be like :

 

LeavesFrom = let fn = (n as any) as list => let kids = GetChildren(n) in if List.IsEmpty(kids) then {n} else List.Combine(List.Transform(kids, each @FN(_))) in fn,
 

 

Hi @CBO2404 

Replace the line where you used Combiner.CombineTextByDelimiter with:

Text.Combine(_, " > ")

That will give you the same result without throwing the error.


Did it work? ✔ Give a Kudo • Mark as Solution – help others too!

Helpful resources

Announcements
August Power BI Update Carousel

Power BI Monthly Update - August 2025

Check out the August 2025 Power BI update to learn about new features.

August 2025 community update carousel

Fabric Community Update - August 2025

Find out what's new and trending in the Fabric community.

Top Kudoed Authors