Forum Discussion

red_arrowhead's avatar
5 years ago
Solved

How to unpivot based on multiple attributes

I have a table where I have data in a form that each type has values from Jan to December and also another Jan to December columns for specific dates in each month for those values.  Example dataset...
  • AlB's avatar
    5 years ago

    red_arrowhead 

    Here you go. I've made it a bit more dynamic so as not to hardcode the names of MonthYear columns. Place the following M code in a blank query to see the steps. The first two steps are just to load the sample data you provided:

    let
        Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("7ZWxDoIwFEX/pbMJvQUERlnc3QxxsxvRxMT4+xZUOKyyNKTLbU66nL6b5nWdOZidOflrSFkbVboms8qcdT9whJxQEErCnlARakIDkCXQQAuD8UYD1F830U10E91EN9FNdBPdRDfRTXSTuew+nZ59399fw91nmPFkqnVFrW3/9OHIx1HGk+EBc6kDOEJOKAglYU+oCDWhAcylDkADLQymkU5uopvoJrqJbqKb6Ca6iW6im+g2l3p8eH8LZzHOMp5MX/Xfr9qatFW32GnaqpusNdKtmkpdU2raqptq9fIG", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Description = _t, #"Cost Type" = _t, #"Jan 20" = _t, #"Feb 20" = _t, #"Mar 20" = _t, #"Apr 20" = _t, #"May 20" = _t, #"Jun 20" = _t, #"Jul 20" = _t, #"Aug 20" = _t, #"Sep 20" = _t, #"Oct 20" = _t, #"Nov 20" = _t, #"Dec 20" = _t, #"Jan 21" = _t, #"Feb 21" = _t, #"Mar 21" = _t, #"Apr 21" = _t, #"May 21" = _t, #"Jun 21" = _t, #"Jul 21" = _t, #"Aug 21" = _t, #"Sep 21" = _t, #"Oct 21" = _t, #"Nov 21" = _t, #"Dec 21" = _t, #"Jan 20.1" = _t, #"Feb 20.1" = _t, #"Mar 20.1" = _t, #"Apr 20.1" = _t, #"May 20.1" = _t, #"Jun 20.1" = _t, #"Jul 20.1" = _t, #"Aug 20.1" = _t, #"Sep 20.1" = _t, #"Oct 20.1" = _t, #"Nov 20.1" = _t, #"Dec 20.1" = _t, #"Jan 21.1" = _t, #"Feb 21.1" = _t, #"Mar 21.1" = _t, #"Apr 21.1" = _t, #"May 21.1" = _t, #"Jun 21.1" = _t, #"Jul 21.1" = _t, #"Aug 21.1" = _t, #"Sep 21.1" = _t, #"Oct 21.1" = _t, #"Nov 21.1" = _t, #"Dec 21.1" = _t]),
        #"Changed Type" = Table.TransformColumnTypes(Source,{{"Description", type text}, {"Cost Type", type text}, {"Jan 20", Int64.Type}, {"Feb 20", Int64.Type}, {"Mar 20", Int64.Type}, {"Apr 20", Int64.Type}, {"May 20", Int64.Type}, {"Jun 20", Int64.Type}, {"Jul 20", Int64.Type}, {"Aug 20", Int64.Type}, {"Sep 20", Int64.Type}, {"Oct 20", Int64.Type}, {"Nov 20", Int64.Type}, {"Dec 20", Int64.Type}, {"Jan 21", Int64.Type}, {"Feb 21", Int64.Type}, {"Mar 21", Int64.Type}, {"Apr 21", Int64.Type}, {"May 21", Int64.Type}, {"Jun 21", Int64.Type}, {"Jul 21", Int64.Type}, {"Aug 21", Int64.Type}, {"Sep 21", Int64.Type}, {"Oct 21", Int64.Type}, {"Nov 21", Int64.Type}, {"Dec 21", Int64.Type}, {"Jan 20.1", type date}, {"Feb 20.1", type date}, {"Mar 20.1", type date}, {"Apr 20.1", type date}, {"May 20.1", type date}, {"Jun 20.1", type date}, {"Jul 20.1", type date}, {"Aug 20.1", type date}, {"Sep 20.1", type date}, {"Oct 20.1", type date}, {"Nov 20.1", type date}, {"Dec 20.1", type date}, {"Jan 21.1", type date}, {"Feb 21.1", type date}, {"Mar 21.1", type date}, {"Apr 21.1", type date}, {"May 21.1", type date}, {"Jun 21.1", type date}, {"Jul 21.1", type date}, {"Aug 21.1", type date}, {"Sep 21.1", type date}, {"Oct 21.1", type date}, {"Nov 21.1", type date}, {"Dec 21.1", type date}}),
      
    
        colsToUnpivot_ = List.Select(List.Select(Table.ColumnNames(#"Changed Type"), each not Text.Contains(_, ".1") ), each not List.Contains({"Description", "Cost Type"}, _)),  
        #"Unpivoted Columns" = Table.Unpivot(#"Changed Type", colsToUnpivot_, "Attribute", "Value"),
        #"Added Custom" = Table.AddColumn(#"Unpivoted Columns", "Date", each Expression.Evaluate("["&[Attribute]&".1]", [_=_]), type date),
        #"Removed Other Columns" = Table.SelectColumns(#"Added Custom",{"Description", "Cost Type", "Attribute", "Value", "Date"})
    in
        #"Removed Other Columns"

    Please mark the question solved when done and consider giving a thumbs up if posts are helpful.

    Contact me privately for support with any larger-scale BI needs, tutoring, etc.

    Cheers