Forum Discussion

valcat27's avatar
valcat27
Icon for Helper III rankHelper III
5 years ago

Create a Crosstab with 1 and 0, based on two columns in Power Query

Hello all,

 

I want to create a crosstab between two columns "ClientID" and "ProductID", in Power Query.

The goal is to see, by row, which products each client bought. For that, I also added a column with the value 1, like that:

ClientIDProductID Value
111
211
321
221
311
441
131
111

 

I tried to use the Group By option in "ProductID" column, selecting "Value" column for Values Column field and "Sum" for Aggregate Value Function field. However, it returned only 3 rows of ClientID's and I do not understand what is failing. 

 

To conclude, this is the crosstab that I want:

ClientID1234
11010
21100
31100
40001

It should be noted that, when a client buys a product once or more, the value that should arise is 1.

The tables showed are just a sample of what I have. 

 

Thanks in advance, 

10 Replies

  • You can get the following pretty easily if you put Client on rows and Product on values in a matrix visual with Value in the values field (pick max for the aggregation):

     

    The difficulty comes if you really need the zeros. Since ClientID and ProductdID are in the same table, DAX does some auto-exist optimization behind the scenes so that the empty combinations are never even evaluated and return nothing. Replacing blank with zero in the measure doesn't help at all since the measure is never evaluated.

     

    To get the zeros, you'd need dimension tables so that Client and Product can be filtered independently. See my comments on this related question too.

  • edhans's avatar
    edhans
    Icon for Community Champion rankCommunity Champion

    valcat27 

     

    I get this:

    I used the client in the rows, product ID in the column of a Matrix visual, then for Values I used the COUNTROWS() function as shown above. That counts the number of times that the customer bought a product. You don't need the Values column.

     

    However, if the Values is an amount to be aggregated and might not always be 1 in your example, then change my measure from:

     

    Total Value = COUNTROWS('Table')

     

    to this:

     

    Total Value = SUM('Table'[Value])
    

     

    In this case, they return the same thing, but they will not if your Values column has anything other than a 1 in it. So it depends on what you want, but if it always has 1, get rid of Values and use the Countrows function in the measure.

     

    Alternatively, if you always want a 1 no matter how many times they buy, consider this:

    Total Value = 
    VAR varRecordCount = COUNTROWS('Table')
    RETURN
    IF(
        varRecordCount,
        1,
        0
    )

    You still don't need the Values column, and if there are any rows, this will return a 1.

  • Hello AlexisOlson and edhans,

     

    I am so sorry... I thought I had selected Power Query forum, but I have just realized that I didn't. 

    I want to apply that transformation in PowerQuery because this is not my final table yet. I will apply more transformations after...

     

    I hope you can still help me and thank you very much for your answers. 

    • edhans's avatar
      edhans
      Icon for Community Champion rankCommunity Champion

      You did select the PQ forum valcat27 - I moved it to the Desktop forum because I thought this was about a Matrix visual. Moving it back. ðŸ˜‚

      That said, see if this works. It pivots your Product ID column and aggregates using the MAX function.

      let
          Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMlTSgeJYnWglIxSeMZBlhCJnhCKHUGkCZJnAeSBxYxQeVGUsAA==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [ClientID = _t, #"ProductID " = _t, Value = _t]),
          #"Pivoted Column" = Table.Pivot(Source, List.Distinct(Source[#"ProductID "]), "ProductID ", "Value", List.Max)
      in
          #"Pivoted Column"

       

      I would need to know more of your data to know if this makes sense though. Generally do you NOT want to denormalize your data in Power Query like this. It makes subseqent DAX harder as a rule, but that is from my perspective here, not in your seat with your entire project laid out before you.

       

      How to use M code provided in a blank query:
      1) In Power Query, select New Source, then Blank Query
      2) On the Home ribbon, select "Advanced Editor" button
      3) Remove everything you see, then paste the M code I've given you in that box.
      4) Press Done
      5) See this article if you need help using this M code in your model.

      • valcat27's avatar
        valcat27
        Icon for Helper III rankHelper III

        Thank you edhans ,

         

        I pasted your code and I got that result but this is just a sample.

        Can you help me to adapt the code to my data? 

         

        This is my last rows when opening "Advanced Editor":

        ...

        #" Value Column added" = Table.AddColumn(#"Sort Columns", "Value", each 1)

        #"Change Type" = Table.TransformColumnTypes(#" Value Column added",{{"ProductID", type text}}),
        in
        #"Change Type"

         

        I tried to add something like that:

        ...

        #" Value Column added" = Table.AddColumn(#"Sort Columns", "Value", each 1)

        #"Change Type" = Table.TransformColumnTypes(#" Value Column added",{{"ProductID", type text}}),

        #"Pivoted Column" = Table.Pivot(#"Change Type", List.Distinct(#"Change Type"[#"ProductID"]), "ProductID", "Value", List.Max)
        in
        #"Pivoted Column"

        but it returns me only four rows and not all rows.