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

Join us for an expert-led overview of the tools and concepts you'll need to become a Certified Power BI Data Analyst and pass exam PL-300. Register now.

Reply
Anonymous
Not applicable

Display Multiple level data

Hello all colleagues,

 

I have a data like this table (SQL)

When a Component has childrent, the price is zero.

LevelParentComponentPrice
1ComputerMonitor0
1ComputerMouse0
1ComputerKeyboard0
1ComputerCable HDMI22
2MonitorLCD Panel28
2MonitorMonitor Frame84
2MonitorMonitor Mainboard0
2MouseButton53
2MouseScroll89
2MouseLaser15
2KeyboardButton 150
2KeyboardButton 246
2KeyboardButton 321
2KeyboardButton 411
3Monitor MainboardChip M15
3Monitor MainboardRam M20
3Monitor MainboardA68
3Monitor MainboardB33

 

The expeted output is somethings like this on Power BI

 

 

Sample.PNG

 

Do you have any solution to tranform data to solve this problem ?

 

Now I have

- Raw data (like the table above) in Database (Synapse);  data will load to data Model (Azure Analysis Service). And Power BI read data from Azure Analysis Service

- I have multiple level (not only 3) so I cannot create a table with multiple column to create hierarchy as normal.

 

I need an ideal to automatically display the data as expeted ( above picture)

 

Thank you

 

 

1 ACCEPTED SOLUTION
Smauro
Solution Sage
Solution Sage

Hi @Anonymous 

 

You could start with this:

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("fZDBC4IwGMX/lbFzB91U7JiTKHIQdRQPswYJ6kTnof++fRqlqDt88Lb3Y3vvS1Ps4h1mqmp6LVsjuaoLrUA5ONut2H0nt8yLfOdKtM8tn4m8lOgU87M5EDIgZPZnwmJ0FbUsAQhXgK9Cx1ZUkCP0LBAXRT0PRCYVol5rVRvh04V3f7SqhBDhfuElohvauP7PmhQfX0XQ3HcsANx6gQWgsALXAniQYQToRmn2KhrE/1m3uJuoBow4VuxgJgitSGSGmn1mHw==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Level = _t, Parent = _t, Component = _t, Price = _t]),
    PreviousStep = Table.TransformColumnTypes(Source,{{"Level", Int64.Type}}),
    
    expandNames = (k, n) => List.Combine(List.Transform({n-k+1..n}, each { Text.From(_) & ".Component", Text.From(_) & ".Price" } )),
    joinK = (tablelist, statetable, k, n) => Table.NestedJoin(tablelist{k}, Text.From(n-k) & ".Component", statetable, Text.From(n-k+1) & ".Parent", "data", JoinKind.LeftOuter),
    recordNames = (rec, series) => List.Accumulate(List.RemoveFirstN(series,1), Record.Field(rec, Text.From(List.Max(series)) & ".Component"), (s, c) => s??Record.Field(rec, Text.From(c) & ".Component")),

    maxLevel = List.Max(PreviousStep[Level]),
    levels = List.Numbers(maxLevel, maxLevel, -1),
    tables = List.Transform(levels, (item) => Table.PrefixColumns(Table.SelectRows(PreviousStep, each [Level] = item), Text.From(item) ) ),

    #"Combine Levels" = List.Accumulate({1..(maxLevel-1)}, tables{0}, (statetable, c) => Table.ExpandTableColumn( joinK(tables, statetable, c, maxLevel) , "data", expandNames(c, maxLevel), expandNames(c, maxLevel))),
    #"Combine Prices" = Table.CombineColumns(#"Combine Levels", List.Transform(levels, each Text.From(_)&".Price"), (x) as number => Number.From(List.Max(x)), "Price"),
    #"Replace null Components" = Table.ReplaceValue(#"Combine Prices", null, (r) => recordNames(r, levels), Replacer.ReplaceValue, List.Transform(levels, each Text.From(_) & ".Component") )
in
    #"Replace null Components"

To see it with your data, replace PreviousStep with your last step's name.

 

 

Best,

Spyros




Spyros Mavroforos

Data Consultant


Find me on LinkedIn or drop me an email

eSpyros

View solution in original post

6 REPLIES 6
Smauro
Solution Sage
Solution Sage

Hi @Anonymous 

 

You could start with this:

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("fZDBC4IwGMX/lbFzB91U7JiTKHIQdRQPswYJ6kTnof++fRqlqDt88Lb3Y3vvS1Ps4h1mqmp6LVsjuaoLrUA5ONut2H0nt8yLfOdKtM8tn4m8lOgU87M5EDIgZPZnwmJ0FbUsAQhXgK9Cx1ZUkCP0LBAXRT0PRCYVol5rVRvh04V3f7SqhBDhfuElohvauP7PmhQfX0XQ3HcsANx6gQWgsALXAniQYQToRmn2KhrE/1m3uJuoBow4VuxgJgitSGSGmn1mHw==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Level = _t, Parent = _t, Component = _t, Price = _t]),
    PreviousStep = Table.TransformColumnTypes(Source,{{"Level", Int64.Type}}),
    
    expandNames = (k, n) => List.Combine(List.Transform({n-k+1..n}, each { Text.From(_) & ".Component", Text.From(_) & ".Price" } )),
    joinK = (tablelist, statetable, k, n) => Table.NestedJoin(tablelist{k}, Text.From(n-k) & ".Component", statetable, Text.From(n-k+1) & ".Parent", "data", JoinKind.LeftOuter),
    recordNames = (rec, series) => List.Accumulate(List.RemoveFirstN(series,1), Record.Field(rec, Text.From(List.Max(series)) & ".Component"), (s, c) => s??Record.Field(rec, Text.From(c) & ".Component")),

    maxLevel = List.Max(PreviousStep[Level]),
    levels = List.Numbers(maxLevel, maxLevel, -1),
    tables = List.Transform(levels, (item) => Table.PrefixColumns(Table.SelectRows(PreviousStep, each [Level] = item), Text.From(item) ) ),

    #"Combine Levels" = List.Accumulate({1..(maxLevel-1)}, tables{0}, (statetable, c) => Table.ExpandTableColumn( joinK(tables, statetable, c, maxLevel) , "data", expandNames(c, maxLevel), expandNames(c, maxLevel))),
    #"Combine Prices" = Table.CombineColumns(#"Combine Levels", List.Transform(levels, each Text.From(_)&".Price"), (x) as number => Number.From(List.Max(x)), "Price"),
    #"Replace null Components" = Table.ReplaceValue(#"Combine Prices", null, (r) => recordNames(r, levels), Replacer.ReplaceValue, List.Transform(levels, each Text.From(_) & ".Component") )
in
    #"Replace null Components"

To see it with your data, replace PreviousStep with your last step's name.

 

 

Best,

Spyros




Spyros Mavroforos

Data Consultant


Find me on LinkedIn or drop me an email

eSpyros

Anonymous
Not applicable

I don't fully understand your code, but it's running well. Great job!

Anonymous
Not applicable

I think this is the answer I need. I will try it and respond the result

Jimmy801
Community Champion
Community Champion

Hello @Anonymous 

 

you can do this in DAX. Add 2 new columns to your data with this formula

NewParent = 
IF (
COUNTROWS (
FILTER ( 'Table', 'Table'[Component] = EARLIER ( 'Table'[Parent] ) )
)
= 0,
'Table'[Component],
'Table'[Parent]
)

 

Path = PATH (
'Table'[Component],
'Table'[NewParent]
)

 

then add new columns as many levels you have. Here the code for level 1

 

Level1 = 
LOOKUPVALUE (
'Table'[Component],
'Table'[Component], PATHITEM ('Table'[Path], 1 )
)

 

If this post helps or solves your problem, please mark it as solution (to help other users find useful content and to acknowledge the work of users that helped you)
Kudoes are nice too

Have fun

Jimmy

Anonymous
Not applicable

But in this case, you still manualy add the level. I dont know how many level will I have. Thanks

Hello @Anonymous 

 

just add enough new columns. Power BI to add a hierarchy needs new columns. 

 

BR

 

Jimmy

Helpful resources

Announcements
Join our Fabric User Panel

Join our Fabric User Panel

This is your chance to engage directly with the engineering team behind Fabric and Power BI. Share your experiences and shape the future.

June 2025 Power BI Update Carousel

Power BI Monthly Update - June 2025

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

June 2025 community update carousel

Fabric Community Update - June 2025

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

Top Solution Authors