1
votes

I have a requirement where I have a table like this -

Actual Table with 2 columns

Column1                                              Column2
ColAValue $$ ColBValue $$                            New Row
ColCValue                                            Above Row
ColCValue2                                           Above Row
$$ ColDValue                                         Above Row
ColAValue $$ ColBValue $$ ColCValue $$ ColDValue     New Row
ColAValue $$ ColBValue $$ ColCValue                  New Row
$$ ColDValue                                         Above Row

I know by requirement, I would have 4 columns in my dataset leaving column 2.

I need my transformed table as a new table using query editor.

This is my expected output,

OutTable with 4 columns

Expected Output

Basically the column values are identified in order by delimiter $$ and if column2 says new row, then it is a new record else, it has to go and append on the current row as a new column value.

How can I transform my Input table to this output table in the query editor?

The final output Data type doesn't matter.

The initial step is to bring the row values from Above row into the New row with a delimiter and have it as a single row.

1

1 Answers

2
votes

The key here is to create a grouping column that assigns each row to its resulting output row number. You can do this by looking up the index of the last row with "New Row" in Column2.

First, create an index column (under the Add Column tab).

Now you can create your grouping custom column by taking the maximal index as described above. The formula might look something like this:

List.Max(
    Table.SelectRows(#"Prev Step Name",
        (here) => [Index] >= here[Index] and here[Column2] = "New Row"
    )[Index]
)

Your table should look like this now:

Group Custom Column

Now we use Group By (under Home tab), grouping by the Group column and aggregating over Column1.

Group By

But we're going to change the aggregation from List.Max to Text.Combine so that the code for this step is

= Table.Group(#"Added Custom", {"Group"},
      {{"Concat", each Text.Combine([Column1]," "), type text}})

Now the table should look like this:

Concatenated

From here, you can do Split Column By Delimiter (under Home tab) using " && " as your delimiter.

Change any column names as desired and delete the Group column if you no longer want it and the result should be your required output.

Desired Output


The M code for the whole query:

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45Wcs7PcQxLzClNVVBRUQBynGAcJR0lv9RyhaD8cqVYHbA6Z7AUUNwxKb8sFVPGCEMKYqQLTn3YbVaAm6iAZgCagwhpR9OB2zWxAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type text) meta [Serialized.Text = true]) in type table [Column1 = _t, Column2 = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Column1", type text}, {"Column2", type text}}),
    #"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 1, 1),
    #"Reordered Columns" = Table.ReorderColumns(#"Added Index",{"Index", "Column1", "Column2"}),
    #"Added Custom" = Table.AddColumn(#"Reordered Columns", "Group", each List.Max(Table.SelectRows(#"Reordered Columns", (here) => [Index] >= here[Index] and here[Column2] = "New Row")[Index]), Int64.Type),
    #"Grouped Rows" = Table.Group(#"Added Custom", {"Group"}, {{"Concat", each Text.Combine([Column1]," "), type text}}),
    #"Split Column by Delimiter" = Table.SplitColumn(#"Grouped Rows", "Concat", Splitter.SplitTextByDelimiter(" $$ ", QuoteStyle.Csv), {"COL1", "COL2", "COL3", "COL4"}),
    #"Removed Columns" = Table.RemoveColumns(#"Split Column by Delimiter",{"Group"})
in
    #"Removed Columns"