Forum Discussion
Unpivot multiple category columns into attributes and values
- 1 year ago
This can be done via List.Range and Table.SelectColumns.
let Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WcssvylUwVNJRckktzkzPAzKc83NzU/NKwIKG+ob6RgZGptjkjYFsI30TiHysDpJRzvl5xSVFpcklmfnIGoyAbFN9Q2OQDhPcykzA5hoZQZTBDTbC5gZTsJFmMBMx5M2BbAt9CyxG4bDcDORpQ4SJOJRZANnmcK/ExgIA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [ID = _t, A.Type = _t, A.Comments = _t, A.Date = _t, B.Type = _t, B.Comments = _t, B.Date = _t]), Process = (tbl,col)=> let s = Table.SelectColumns(tbl,{"ID"} & col), newcol = List.Transform(col, each if Text.Length(_)>2 then Text.Range(_,2) else _), t = Table.RenameColumns(s,List.Zip({col,newcol})) in Table.AddColumn(t,"Category",each Text.Start(col{1},1)), Combined = Process(Source,List.Range(Table.ColumnNames(Source),1,3)) & Process(Source, List.Range(Table.ColumnNames(Source),4,3)), #"Reordered Columns" = Table.ReorderColumns(Combined,{"ID", "Category", "Type", "Comments", "Date"}) in #"Reordered Columns"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 entire Source step with your own source.
- 1 year ago
hello arpitprakash89
please check if this accomodate your need.
1. Merged type, comment, and date of A with any delimiter (i used colon). then put "A" as column name.
2. do exact same for "B"
3. unpivot A and B column
4. split the value column by colon delimiter since i used colon as delimiter when merging
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WcssvylUwVNJRckktzkzPAzKc83NzU/NKwIKG+ob6RgZGptjkjYFsI30TiHysDpJRzvl5xSVFpcklmfnIGoyAbFN9Q2OQDhPcykzA5hoZQZTBDTbC5gZTsJFmMBMx5M2BbAt9CyxG4bDcDORpQ4SJOJRZANnmcK/ExgIA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [ID = _t, #"A.Type " = _t, A.Comments = _t, A.Date = _t, B.Type = _t, B.Comments = _t, B.Date = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"ID", type text}, {"A.Type ", type text}, {"A.Comments", type text}, {"A.Date", type date}, {"B.Type", type text}, {"B.Comments", type text}, {"B.Date", type date}}),
#"Merged Columns" = Table.CombineColumns(Table.TransformColumnTypes(#"Changed Type", {{"A.Date", type text}}, "en-US"),{"A.Type ", "A.Comments", "A.Date"},Combiner.CombineTextByDelimiter(":", QuoteStyle.None),"A"),
#"Merged Columns1" = Table.CombineColumns(Table.TransformColumnTypes(#"Merged Columns", {{"B.Date", type text}}, "en-US"),{"B.Type", "B.Comments", "B.Date"},Combiner.CombineTextByDelimiter(":", QuoteStyle.None),"B"),
#"Unpivoted Columns" = Table.UnpivotOtherColumns(#"Merged Columns1", {"ID"}, "Attribute", "Value"),
#"Split Column by Delimiter" = Table.SplitColumn(#"Unpivoted Columns", "Value", Splitter.SplitTextByDelimiter(":", QuoteStyle.Csv), {"Value.1", "Value.2", "Value.3"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Value.1", type text}, {"Value.2", type text}, {"Value.3", type date}})
in
#"Changed Type1"Hope this will help.
Thank you.
That's actually much simpler to implement.
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("hVBNi8IwEP0rQ89Kk7jx42pFdkGWBb1JD0EHLdgZSXPY/nsn1ZaIuwiZMC95M+/N7PfZmn09VjobZUvfHhB2+Cv5F8GP55PHphFklVwF1zVSaCBytcmNkmM+0p8I4G2Uo17VRFVmQvh0vmZq782uFwwYRdSTrkm6rOSFCTbsvasokk2uF9GQlfybA2yD8wGPD/7QxHaDOjpWsHOdCuhcW6m0L2PPVOJ18lL4v9PI1fmkt/PXGgbuVMC6IoLijC1SN4sWS/Nku6lMWd4A", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Form = _t, #"Model.Assigned To" = _t, Model.Status = _t, Model.Completion = _t, Model.Comments = _t, #"Model.Due Date" = _t, Other.Comments = _t, #"Other.Assigned To" = _t, #"Other.Due Date" = _t, Other.Status = _t, Other.Completion = _t, #"Configure Plans and Specs.Comments" = _t, #"Configure Plans and Specs.Assigned To" = _t, #"Configure Plans and Specs.Due Date" = _t, #"Configure Plans and Specs.Status" = _t, #"Configure Plans and Specs.Completion" = _t]),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(Source, {"Form"}, "Attribute", "Value"),
#"Filtered Rows" = Table.SelectRows(#"Unpivoted Other Columns", each ([Value] <> " ")),
#"Split Column by Delimiter" = Table.SplitColumn(#"Filtered Rows", "Attribute", Splitter.SplitTextByEachDelimiter({"."}, QuoteStyle.Csv, false), {"Deliverable", "Attribute.2"}),
#"Pivoted Column" = Table.Pivot(#"Split Column by Delimiter", List.Distinct(#"Split Column by Delimiter"[Attribute.2]), "Attribute.2", "Value")
in
#"Pivoted Column"Shoot, it seems I have multiple rows for the same Form-Deliverable-Type, and pivoting gives an error. For example, the last row is for the same Form as the first.
| Form | Model.Assigned To | Model.Status | Model.Completion | Model.Comments | Model.Due Date | Other.Comments | Other.Assigned To | Other.Due Date | Other.Status | Other.Completion | Configure Plans and Specs.Comments | Configure Plans and Specs.Assigned To | Configure Plans and Specs.Due Date | Configure Plans and Specs.Status | Configure Plans and Specs.Completion |
| Form-01 | Bryce | In Progress | 50 | Comments 1 | 12/20/2024 | Comments 4 | |||||||||
| Form-02 | Boone | Complete | 100 | Comments 2 | Denton | 2/19/2025 | Not Started | Comments 5 | Brandi | 1/15/205 | In Progress | 70 | |||
| Form-03 | Brandi | Complete | 100 | Comments 3 | 1/3/2025 | Comments 6 | Finn | 11/18/2024 | Complete | 100 | |||||
| Form-01 | Boone | In Progress | 30 | Comment 7 | 2/5/2025 |
- lbendlin1 year ago
Super User
what's the expected output? You can add an index column to the raw data to remove the pivot ambiguity.
- arpitprakash891 year agoFrequent Visitor
The difference would be the additional second line to the original output -
Form Deliverable Assigned To Status Completion Comments Due Date Form-01 Model Bryce In Progress 50 Comments 1 12/20/2024 Form-01 Model Boone In Progress 30 Comment 7 2/5/2025 Form-01 Other Comments 4 Form-01 Configure Plans and Specs Form-02 Model Boone Complete 100 Form-02 Other Denton Not Started 1/15/2025 Form-02 Configure Plans and Specs Brandi In Progress 70 Form-03 Model Brandi Complete 100 1/3/2025 Form-03 Other Form-03 Configure Plans and Specs Finn Complete 100 11/18/2024 - lbendlin1 year ago
Super User
let Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("hZHNCsIwDIBfpew8adNZp1eVgRcRPI4dhisy2FrpevHtTaablU2F/iTN35c0z6PMunYhIIqjrbtfNN4Hw07OXp3uOtSUwGNn21Yb3zHyA8mlwCWXoYUU9ncX8VBRUkVrjX4muTXakwjio54Movf4Yg0KksOG6iuUj9azsy+d19XLbYxVfU+lqWqyAAeFQWrSYCoCqiSM+Y5FbsCTAWKu19F3hUpWGwIHhFgHkwuzvxlgmAybsCYBBUv7UahfEDMfUDwA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Form = _t, #"Model.Assigned To" = _t, Model.Status = _t, Model.Completion = _t, Model.Comments = _t, #"Model.Due Date" = _t, Other.Comments = _t, #"Other.Assigned To" = _t, #"Other.Due Date" = _t, Other.Status = _t, Other.Completion = _t, #"Configure Plans and Specs.Comments" = _t, #"Configure Plans and Specs.Assigned To" = _t, #"Configure Plans and Specs.Due Date" = _t, #"Configure Plans and Specs.Status" = _t, #"Configure Plans and Specs.Completion" = _t]), #"Added Index" = Table.AddIndexColumn(Source, "Index", 0, 1, Int64.Type), #"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Added Index", {"Form", "Index"}, "Attribute", "Value"), #"Filtered Rows" = Table.SelectRows(#"Unpivoted Other Columns", each ([Value] <> " ")), #"Split Column by Delimiter" = Table.SplitColumn(#"Filtered Rows", "Attribute", Splitter.SplitTextByEachDelimiter({"."}, QuoteStyle.Csv, false), {"Deliverable", "Attribute.2"}), #"Pivoted Column" = Table.Pivot(#"Split Column by Delimiter", List.Distinct(#"Split Column by Delimiter"[Attribute.2]), "Attribute.2", "Value") in #"Pivoted Column"