Forum Discussion

deannapi's avatar
deannapi
Frequent Visitor
2 years ago
Solved

Concatenate one column per ID

I have a table with multiple IDs and each ID is repeated with another column [Stage] values.

IDStage
1234Sent
1234Created
1234Waiting
1234Waiting
9874Waiting
9874Sent
6542Offer
6542Waiting
6542Sent

I want to create a column that is a concatenation of stages that occur per ID - but I only care about "Sent" and "Waiting" and "Offer". If other stages occur, leave the custom column blank

IDStage
1234Sent, Waiting
1234 
1234Sent, Waiting
1234Sent, Waiting
9874Sent, Waiting
9874Sent, Waiting
6542Sent, Waiting, Offer
6542Sent, Waiting, Offer
6542Sent, Waiting, Offer
  • let
      Source = Table.FromRows(
        Json.Document(
          Binary.Decompress(
            Binary.FromText(
              "i45WMjQyNlHSUQpOzStRitWB852LUhNLUlOQhcITM0sy89JxCVlamOMQgpttZmpiBOT7p6WlFiELIOuBCkH0xAIA", 
              BinaryEncoding.Base64
            ), 
            Compression.Deflate
          )
        ), 
        let
          _t = ((type nullable text) meta [Serialized.Text = true])
        in
          type table [ID = _t, Stage = _t]
      ), 
      #"Replaced Value" = Table.ReplaceValue(
        Source, 
        each [Stage], 
        (k) =>
          let
            ld = List.Distinct(
              Table.SelectRows(
                Source, 
                each [ID] = k[ID] and List.Contains({"Sent", "Waiting", "Offer"}, [Stage])
              )[Stage]
            )
          in
            if List.Contains(ld, k[Stage]) then Text.Combine(ld, ", ") else null, 
        Replacer.ReplaceValue, 
        {"Stage"}
      )
    in
      #"Replaced Value"

    How to use this code: Create a new Blank Query. Click on "Advanced Editor". Replace the code in the window with the code provided here. Click "Done". Once you examined the code, replace the Source step with your own source.

  • Hi deannapi, another solution:

     

    Before

     

    After

     

    let
        Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMjQyNlHSUQpOzStRitWB852LUhNLUlOQhcITM0sy89JxCVlamOMQgpttZmpiBOT7p6WlFiELIOuBCkH0xAIA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [ID = _t, Stage = _t]),
        Stages = List.Buffer({"Sent", "Waiting", "Offer"}),
        GroupedRows = Table.Group(Source, {"ID"}, {{"All", each 
            [ a = List.Intersect({Stages, [Stage]}, Comparer.OrdinalIgnoreCase),
              b = Text.Combine(a, ", "),
              c = Table.ReplaceValue(_, each [Stage], each if List.Contains(a, [Stage]) then b else null, Replacer.ReplaceValue, {"Stage"})
            ][c], type table}}),
        CombinedAll = Table.Combine(GroupedRows[All])
    in
        CombinedAll

     

2 Replies

  • let
      Source = Table.FromRows(
        Json.Document(
          Binary.Decompress(
            Binary.FromText(
              "i45WMjQyNlHSUQpOzStRitWB852LUhNLUlOQhcITM0sy89JxCVlamOMQgpttZmpiBOT7p6WlFiELIOuBCkH0xAIA", 
              BinaryEncoding.Base64
            ), 
            Compression.Deflate
          )
        ), 
        let
          _t = ((type nullable text) meta [Serialized.Text = true])
        in
          type table [ID = _t, Stage = _t]
      ), 
      #"Replaced Value" = Table.ReplaceValue(
        Source, 
        each [Stage], 
        (k) =>
          let
            ld = List.Distinct(
              Table.SelectRows(
                Source, 
                each [ID] = k[ID] and List.Contains({"Sent", "Waiting", "Offer"}, [Stage])
              )[Stage]
            )
          in
            if List.Contains(ld, k[Stage]) then Text.Combine(ld, ", ") else null, 
        Replacer.ReplaceValue, 
        {"Stage"}
      )
    in
      #"Replaced Value"

    How to use this code: Create a new Blank Query. Click on "Advanced Editor". Replace the code in the window with the code provided here. Click "Done". Once you examined the code, replace the Source step with your own source.

  • dufoq3's avatar
    dufoq3
    Community Champion

    Hi deannapi, another solution:

     

    Before

     

    After

     

    let
        Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMjQyNlHSUQpOzStRitWB852LUhNLUlOQhcITM0sy89JxCVlamOMQgpttZmpiBOT7p6WlFiELIOuBCkH0xAIA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [ID = _t, Stage = _t]),
        Stages = List.Buffer({"Sent", "Waiting", "Offer"}),
        GroupedRows = Table.Group(Source, {"ID"}, {{"All", each 
            [ a = List.Intersect({Stages, [Stage]}, Comparer.OrdinalIgnoreCase),
              b = Text.Combine(a, ", "),
              c = Table.ReplaceValue(_, each [Stage], each if List.Contains(a, [Stage]) then b else null, Replacer.ReplaceValue, {"Stage"})
            ][c], type table}}),
        CombinedAll = Table.Combine(GroupedRows[All])
    in
        CombinedAll