Forum Discussion

Anonymous's avatar
Anonymous
Not applicable
5 years ago
Solved

Display Multiple level data

Hello all colleagues,   I have a data like this table (SQL) When a Component has childrent, the price is zero. Level Parent Component Price 1 Computer Monitor 0 1 Computer Mouse ...
  • Smauro's avatar
    5 years ago

    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