Forum Discussion

COIL-ibesmond's avatar
1 year ago
Solved

Transforming data using Pivot, Unpivot and Transpose, Need to Pivot multiple columns

I've already done a bunch of ETL on this data, but I'm stuck trying to pivot (I think) Value and Type, so it shows Date and Amount as the column headers.  I feel pivot is what I need, but you can only pivot on column.  I need to pivot two columns.  I would prefer to avoid splitting the data and merging them back together. I tried to concatenate Type and Value, and then pivot the data, but I got an error on the rows with dates and wasn't sure how to proceed, so I didn't try to pivot the concatenated column.

 

Can someone assist me with how to transform this table:

 

PersonValueTypeActivity
128/2/2023 12:00:00 AMDateFirst Order
12500AmtFirst Order
126/21/2023 12:00:00 AMDateSecond Order
12900AmtSecond Order
128/31/2024 12:00:00 AMDateThird Order
12750AmtThird Order
126/21/2023 12:00:00 AMDateFourth Order
12800AmtFourth Order
128/1/2023 12:00:00 AMDateFifth Order
12200AmtFifth Order
121/1/9999 12:00:00 AMDateSixth Order
12450AmtSixth Order
1210/26/2022 5:30:00 PMDateSeventh Order
12780AmtSeventh Order

 

Into this table:

 

PersonActivityDateAmt
12First Order8/2/2023 12:00:00 AM500
12Second Order6/21/2023 12:00:00 AM900
12Third Order8/31/2024 12:00:00 AM750
12Fourth Order6/21/2023 12:00:00 AM800
12Fifth Order8/1/2023 12:00:00 AM200
12Sixth Order1/1/9999 12:00:00 AM450
12Seventh Order10/26/2022 5:30:00 PM780


Thank you.

  • AlienSx's avatar
    AlienSx
    1 year ago
    let
        Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
        activities = List.Buffer({1..(Table.ColumnCount(Source) - 1) / 2}),
        tr = List.TransformMany(
            Table.ToRows(Source), 
            (x) => ((w) => 
                List.Zip(
                    {
                        activities,
                        List.Alternate(w, 1, 1, 1),
                        List.Alternate(w, 1, 1)
                    }
                )
            )(List.Skip(x)),
            (x, y) => {x{0}} & y
        ), 
        z = Table.FromRows(tr, {"Person", "Activity", "Date", "Amount"})
    in
        z
  • dufoq3's avatar
    dufoq3
    1 year ago

    Hi COIL-ibesmond, different approach:

     

     

    let
        Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("Zc1RCsAgDAPQu/RbZpNp513E+1/DMWVd2V94JKR3gSRBRma5Q1U9VB+pS8ylLaELuAjqdmoYjtSFscx/Ge8xM8o2+5hta2684naMCQ==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Person = _t, #"1st Date" = _t, #"1st Amt" = _t, #"2nd Date" = _t, #"2nd Amt" = _t, #"3rd Date" = _t, #"3rd Amt" = _t, #"4th Date" = _t, #"4th Amt" = _t, #"5th Date" = _t, #"5th Amt" = _t]),
        Unpivoted = Table.UnpivotOtherColumns(Source, {"Person"}, "Attribute", "Value"),
        Splitted = Table.SplitColumn(Unpivoted, "Attribute", Splitter.SplitTextByDelimiter(" ", QuoteStyle.Csv), {"Activity", "Attribute.2"}),
        Pivoted = Table.Pivot(Splitted, List.Distinct(Splitted[Attribute.2]), "Attribute.2", "Value"),
        ChangedType = Table.TransformColumnTypes(Pivoted,{{"Person", Int16.Type}, {"Date", type date}, {"Amt", type number}}, "en-US"),
        SortedRows = Table.Sort(ChangedType,{{"Activity", Order.Ascending}, {"Person", Order.Ascending}})
    in
        SortedRows

6 Replies

  • use this formula

     

     

    let
        Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("hZFdC8IgFIb/ing9UM++3O4GsbsoqLvhRTRjXmwDs+jnZyOYS7dEFOR5H47nNA1mgCPMCRCgECMGJaV2o2pvn3cXI+1VK3036KBbqbGIvpGUUntWvVkDMgJsQ3qS13Fof0OFYw0TnMSTNglrz53SXiZPZ2sQ+FNrPT606bxK3A6ECbJpVTc/Aou2BgBmnYVdK11VLz+SON8PAowSyD6VAkrLeJIeF6N6ysFP5dyd1YxgId4=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Person = _t, Value = _t, Type = _t, Activity = _t]),
        Custom1 = Table.Split(Source,2),
        Custom2 = List.Transform(Custom1,each [Person=_{0}[Person],Date=_{0}[Value],Activity=_{0}[Activity],AMT=_{1}[Value]]),
        Custom3 = Table.FromRecords(Custom2)
    in
        Custom3
  • Joe_Barry's avatar
    Joe_Barry
    Solution Sage

    Hi COIL-ibesmond 

     

    Does the dat come out of the source like that? It looks like it's been unpivoted already, check the steps in your query and test by removing the step.

    If it hasn't been unpivoted, just highlight the Type column, then go to the Transform tab in the ribbon and click on Pivot column. In the Values Column field make sure the Value columni schosen and Advanced Options choose Don't Aggregate

    Then you get the result you're looking for



    Joe

    • COIL-ibesmond's avatar
      COIL-ibesmond
      Helper I

      Yeah - I did some previous ETL.  The original data comes out in one row per person.

      Person1st Date1st Amt2nd Date2nd Amt3rd Date3rd Amt4th Date4th Amt5th Date5th Amt
      11/1/24500.001/5/24600.001/8/24200.001/12/241000.001/30/24600.00
      21/12/241200.001/30/241500.002/14/241600.002/16/241800.002/27/241500.00

       

      With the attempt of transforming it into:

       

      PersonActivity1st Date1st Amt
      11st 1/1/2024500
      21st 1/12/20241200
      12nd1/5/2024600
      22nd1/30/20241500
      13rd1/8/2024200
      23rd2/14/20241600
      14th1/12/20241000
      24th2/16/20241800
      15th1/30/2024600
      25th2/27/20241500
      • dufoq3's avatar
        dufoq3
        Community Champion

        Hi COIL-ibesmond, different approach:

         

         

        let
            Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("Zc1RCsAgDAPQu/RbZpNp513E+1/DMWVd2V94JKR3gSRBRma5Q1U9VB+pS8ylLaELuAjqdmoYjtSFscx/Ge8xM8o2+5hta2684naMCQ==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Person = _t, #"1st Date" = _t, #"1st Amt" = _t, #"2nd Date" = _t, #"2nd Amt" = _t, #"3rd Date" = _t, #"3rd Amt" = _t, #"4th Date" = _t, #"4th Amt" = _t, #"5th Date" = _t, #"5th Amt" = _t]),
            Unpivoted = Table.UnpivotOtherColumns(Source, {"Person"}, "Attribute", "Value"),
            Splitted = Table.SplitColumn(Unpivoted, "Attribute", Splitter.SplitTextByDelimiter(" ", QuoteStyle.Csv), {"Activity", "Attribute.2"}),
            Pivoted = Table.Pivot(Splitted, List.Distinct(Splitted[Attribute.2]), "Attribute.2", "Value"),
            ChangedType = Table.TransformColumnTypes(Pivoted,{{"Person", Int16.Type}, {"Date", type date}, {"Amt", type number}}, "en-US"),
            SortedRows = Table.Sort(ChangedType,{{"Activity", Order.Ascending}, {"Person", Order.Ascending}})
        in
            SortedRows
  • Anonymous's avatar
    Anonymous
    Not applicable

    Hi COIL-ibesmond ,

     

    You can also filter and then merge queries:

    let
        Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("hZFdC8IgFIb/ing9UI9zX3eD2F0U1N3YRTRjXrSBWfTzsxGk6ZaIgjzvw/GctsUMcIILAgQocMSgotRuVG/t8+ZkpL0apW8G7XQvNe6ST0RQas/6apaAjABbkR7keRr731DpWONEQfisTePa46B0kMnF1xoF/tTaTHdthqAStwNxgqxa1SWMgNfWCMCss7RroavqGUZS5/tRgFEC2btSQKLis3TvjeohxzCVF+6sPKR7AQ==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Person = _t, Value = _t, Type = _t, Activity = _t]),
        tab1 = Table.SelectRows(Source, each ([Type] = "Date")),
        tab2 = Table.SelectRows(Source, each ([Type] = "Amt")),
        #"Merged Queries" = Table.NestedJoin(tab1, {"Person", "Activity"}, tab2, {"Person", "Activity"}, "tab2", JoinKind.LeftOuter),
        #"Expanded tab2" = Table.ExpandTableColumn(#"Merged Queries", "tab2", {"Value"}, {"tab2.Value"}),
        #"Removed Columns" = Table.RemoveColumns(#"Expanded tab2",{"Type"}),
        #"Renamed Columns" = Table.RenameColumns(#"Removed Columns",{{"Value", "Date"}, {"tab2.Value", "Amt"}}),
        #"Changed Type" = Table.TransformColumnTypes(#"Renamed Columns",{{"Date", type datetime}, {"Amt", Int64.Type}})
    in
        #"Changed Type"

    Best Regards,
    Gao

    Community Support Team

     

    If there is any post helps, then please consider Accept it as the solution  to help the other members find it more quickly.
    If I misunderstand your needs or you still have problems on it, please feel free to let us know. Thanks a lot!

    How to get your questions answered quickly --  How to provide sample data in the Power BI Forum