Home » Top Products!

Top Products!

In the Question table, daily sales information is provided. Extract the top two products for each month and their share of total sales per month. For example, in Month 3, products B, A, D, and C were sold in quantities of 67, 16, 21, and 24, respectively. Therefore, the top two products for this month are B and C, with sales shares of 52% and 19%, respectively, while the remaining 29% of sales are attributed to other products.

📌 Challenge Details and Links
Challenge Number: 96
Challenge Difficulty: ⭐⭐⭐⭐
📥Download Sample File
📥Link to the solutions on LinkedIn
📥Link to the solution on YouTube

Solving the challenge of Top Products! with Power Query

Power Query solution 1 for Top Products!, proposed by Zoran Milokanović:
let
  Source = Excel.CurrentWorkbook(){[Name = "Input"]}[Content], 
  S = Table.FromRows(
    List.Combine(
      Table.Group(
        Table.Group(
          Table.TransformColumns(Source, {"Date", Date.Month}), 
          {"Date", "Product"}, 
          {"Quantity", each List.Sum([Quantity])}
        ), 
        "Date", 
        {
          "A", 
          each 
            let
              t = Table.Sort(_, {"Quantity", 1}), 
              p = t[Product], 
              q = t[Quantity], 
              c = List.Count(p)
            in
              List.Transform(
                {0 .. {2, c}{Byte.From(c < 2)}}, 
                (m) =>
                  let
                    f = Byte.From(m > 1)
                  in
                    {
                      [Date]{0}, 
                      {p{m}, "Other"}{f}, 
                      {q{m}, List.Sum(List.Skip(q, m))}{f} / List.Sum(q)
                    }
              )
        }
      )[A]
    ), 
    {"Month", "Product", "% of Month sales"}
  )
in
  S
Power Query solution 2 for Top Products!, proposed by 🇵🇪 Ned Navarrete C.:
let
  S = Excel.CurrentWorkbook(){[Name = "Tabla1"]}[Content], 
  M = Table.TransformColumns(S, {{"Date", Date.Month}}), 
  G = Table.Group(
    M, 
    {"Date"}, 
    {
      {
        "X", 
        each [
          a = List.Sum(_[Quantity]), 
          b = Table.Group(_, {"Date", "Product"}, {{"P", each List.Sum([Quantity])}}), 
          c = Table.TransformColumns(b, {{"P", each _ / a}}), 
          d = Table.Sort(c, {"P", 1}), 
          e = Table.FirstN(d, 2), 
          f = Table.ToRecords(e), 
          g = [Date = [Date]{0}, Product = "Other", P = 1 - List.Sum(e[P])], 
          h = Table.FromRecords(f & {g})
        ][h]
      }
    }
  ), 
  R = Table.ExpandTableColumn(
    G[[X]], 
    "X", 
    {"Date", "Product", "P"}, 
    {"Month", "Product", "% of Month sales"}
  )
in
  R
Power Query solution 3 for Top Products!, proposed by Brian Julius:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  ExtractMo = Table.TransformColumns(Source, {{"Date", Date.Month}}), 
  Group = Table.Group(ExtractMo, {"Date", "Product"}, {{"Q", each List.Sum([Quantity])}}), 
  ReGroup = Table.Group(Group, {"Date"}, {{"MonSales", each List.Sum([Q])}, {"All", each _}}), 
  AddRank = Table.AddColumn(
    ReGroup, 
    "RankCol", 
    each Table.AddRankColumn(
      [All], 
      "Rank", 
      {"Q", Order.Descending}, 
      [RankKind = RankKind.Competition]
    )
  ), 
  Expand = Table.RemoveColumns(
    Table.ExpandTableColumn(AddRank, "RankCol", {"Product", "Q", "Rank"}, {"Prod", "Q", "Rank"}), 
    "All"
  ), 
  AddOther = Table.AddColumn(Expand, "Product", each if [Rank] <= 2 then [Prod] else "Other"), 
  SumGT2 = Table.RenameColumns(
    Table.Group(AddOther, {"Date", "MonSales", "Product"}, {{"Q", each List.Sum([Q])}}), 
    {"Date", "Month"}
  ), 
  AddPct = Table.RemoveColumns(
    Table.AddColumn(SumGT2, "% Mon Sales", each Number.Round([Q] / [MonSales], 2), Percentage.Type), 
    {"MonSales", "Q"}
  )
in
  AddPct
Power Query solution 4 for Top Products!, proposed by Aditya Kumar Darak 🇮🇳:
let
  Source = Excel.CurrentWorkbook(){[Name = "data"]}[Content], 
  Month = Table.AddColumn(Source, "Month", each Date.Month([Date])), 
  Group1 = Table.Group(Month, {"Month", "Product"}, {"Qty", each List.Sum([Quantity])}), 
  Group2 = Table.Group(
    Group1, 
    "Month", 
    {
      "All", 
      each [
        M = Table.MaxN(_, "Qty", 2)[[Product], [Qty]], 
        T = Table.TransformColumns(M, {"Qty", (f) => f / List.Sum([Qty])}), 
        O = #table({"Product", "Qty"}, {{"Other", 1 - List.Sum(T[Qty])}}), 
        R = T & O
      ][R], 
      type table [Product, Qty = Percentage.Type]
    }
  ), 
  Return = Table.ExpandTableColumn(Group2, "All", {"Product", "Qty"}, {"Product", "Percentage"})
in
  Return
Power Query solution 5 for Top Products!, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
Month = Table.AddColumn(Source, "Month", each Date.Month([Date])),
Group = Table.Group(Month, "Month", {{"All", each 
 let
 a = Table.Group(_ [[Product],[Quantity]], "Product", {"Quantity", each 
 List.Sum([Quantity])}),
 b = List.Sum([Quantity]),
 c = List.Transform(Table.ToRows(a), each {_{0},Number.ToText(_{1}/b, "p0")}),
 d = List.Sort(c, {each Number.FromText(_{1}),1}),
 e = List.FirstN(d,2),
 f = {"Other", Number.ToText(List.Sum(List.Transform(List.Skip(d,2), 
 each Number.From(_{1}))), "P0")},
 g = Table.FromRows(e&{f}, {"Product", "% of Month sales"})
 in g}}),
Sol = Table.ExpandTableColumn(Group, "All", Table.ColumnNames(Group[All]{0}))
in
Sol
Power Query solution 6 for Top Products!, proposed by Kris Jaganah:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Mth = Table.TransformColumns(Source, {"Date", Date.Month}), 
  Per = Table.AddColumn(
    Mth, 
    "Percent", 
    each List.Sum(
      Table.SelectRows(Mth, (x) => x[Date] = [Date] and x[Product] = [Product])[Quantity]
    )
      / List.Sum(Table.SelectRows(Mth, (x) => x[Date] = [Date])[Quantity])
  ), 
  Group = Table.Group(
    Per, 
    {"Date"}, 
    {
      "All", 
      each Table.Group(
        Table.AddColumn(
          Table.AddIndexColumn(Table.Distinct(Table.Sort(_, {"Percent", 1}), "Product"), "I", 1, 1), 
          "Add", 
          each if [I] > 2 then "Other" else [Product]
        ), 
        {"Add"}, 
        {"All", each Number.Round(List.Sum([Percent]), 2)}
      )
    }
  ), 
  Xpand = Table.ExpandTableColumn(Group, "All", {"Add", "All"}, {"Product", "% of Month sales"}), 
  Type = Table.TransformColumnTypes(Xpand, {{"% of Month sales", Percentage.Type}}), 
  Rename = Table.RenameColumns(Type, {{"Date", "Month"}})
in
  Rename
Power Query solution 7 for Top Products!, proposed by 🇮🇷 Navid Esmaeilzadeh اسماعیل زاده:
let
S = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
A = Table.TransformColumns(S,{{"Date", Date.Month, Int64.Type}}),
B = Table.Group(A, {"Date"}, {{"T", each _, type table [Date=number, Product=text, Quantity=number]}}),
C=(x)=>
let
a = Table.Group(x, {"Product"}, {{"Q", each List.Sum([Quantity]), type number}}),
b = Table.Sort(a,{{"Q", Order.Descending}}),
c = Table.AddIndexColumn(b, "I", 1, 1, Int64.Type),
d = Table.AddColumn(c, "%", each [Q]/List.Sum(c[Q])),
e = Table.AddColumn(d, "P", each if [I]<=2 then [Product] else "Other"),
f = Table.Group(e, {"P"}, {{"% of Month Sales", each List.Sum([#"%"]), type number}})
in
f,
D = Table.AddColumn(B, "C", each C([T])),
E = Table.SelectColumns(D,{"Date", "C"}),
F = Table.ExpandTableColumn(E, "C", {"P", "% of Month Sales"}, {"P", "% of Month Sales"}),
G = Table.TransformColumnTypes(F,{{"% of Month Sales", Percentage.Type}}),
H = Table.TransformColumns(G,{{"% of Month Sales", each Number.Round(_, 2), Percentage.Type}}),
I = Table.RenameColumns(H,{{"Date", "Month"}, {"P", "Product"}})
in
I
Power Query solution 8 for Top Products!, proposed by Szabolcs Phraner:
let Source = ,
//create Month column while setting data types
 PrepareRows = Table.FromRecords(
 Table.TransformRows( Source,
each
[Month = Date.Month( Date.FromText([Date],[Format = "d/M/yyyy"]) ), Product = [Product], Quantity = Int64.From([Quantity])]
)
, type table [Month = Int64.Type, Product = Text.Type, Quantity = Int64.Type ]
),

 Aggregate_Quantity = Table.Group(PrepareRows, {"Month", "Product"}, {{"Quantity", each List.Sum([Quantity]), Int64.Type}}),
 GroupMonths = Table.Group(Aggregate_Quantity, {"Month"}, {{"Result",
 each 
 [
 total = List.Sum([Quantity]),
 top_prod = Table.MaxN(_,"Quantity",2),
 insert_other = Table.InsertRows(top_prod,2, {[Month = null, Product = "Other", Quantity = total - List.Sum(top_prod[Quantity]) ]}),
 calc_percentage = Table.AddColumn(insert_other, "% of Month sales", each Number.Round( [Quantity] / total,2) , Percentage.Type )
 ] [ calc_percentage]
,type table [Product = text, #"% of Month sales" = Percentage.Type]
}}),
 Expand_ResultTable = Table.ExpandTableColumn(GroupMonths, "Result", {"Product", "% of Month sales"}, {"Product", "% of Month sales"})
in
 Expand_ResultTable

Solving the challenge of Top Products! with Excel

Excel solution 1 for Top Products!, proposed by Bo Rydobon 🇹🇭:
=LET(
    m,
    MONTH(
        B3:B20
    ),
    p,
    C3:C20,
    q,
    D3:D20,
    REDUCE(
        I2:K2,
        UNIQUE(
            m
        ),
        LAMBDA(
            a,
            i,
            LET(
                g,
                GROUPBY(
                    p,
                    q,
                    SUM,
                    ,
                    0,
                    -2,
                    m=i
                ),
                h,
                TAKE(
                    g,
                    2
                ),
                k,
                IFERROR(
                    h/SUM(
                        g
                    ),
                    h
                ),
                
                VSTACK(
                    a,
                    IFNA(
                        HSTACK(
                            i,
                            VSTACK(
                                k,
                                HSTACK(
                                    "Other",
                                    1-SUM(
                                        k
                                    )
                                )
                            )
                        ),
                        i
                    )
                )
            )
        )
    )
)
Excel solution 2 for Top Products!, proposed by 🇰🇷 Taeyong Shin:
=LET(
 h,
     SORT(
         GROUPBY(
             HSTACK(
                 MONTH(
                     B3:B20
                 ),
                  C3:C20
             ),
              D3:D20,
              SUM,
              ,
              0
         ),
          {1,
         3},
          {1,
         -1}
     ), c,
     TAKE(
         h,
          ,
          1
     ), s,
     SEQUENCE(
         ROWS(
             c
         )
     ), n,
     MAP(MMULT((s >= TOROW(
         s
     )) * (c = TOROW(
             c
         )),
     SIGN(
             c
         )),
     LAMBDA(
         x,
          MIN(
              x,
               3
          )
     )), f,
     LAMBDA(
         v,
         f,
          DROP(
              DROP(
                  PIVOTBY(
                      c,
                       n,
                       v,
                       f,
                       ,
                       -1,
                       ,
                       ,
                       ,
                       ,
                       1
                  ),
                   2,
                   -1
              ),
               ,
               1
          )
     ), HSTACK(      TOCOL(
          IFNA(
              UNIQUE(
             c
         ),
               TAKE(
                   h,
                    1
               )
          )
      ),      TOCOL(
          IF(
              {1,
              1,
              0},
               f(
                   INDEX(
                       h,
                        ,
                        2
                   ),
                    CONCAT
               ),
               "Other"
          )
      ),      TOCOL(
          f(
              TAKE(
                  h,
                   ,
                   -1
              ),
               PERCENTOF
          )
      ) )
)
Excel solution 3 for Top Products!, proposed by محمد حلمي:
=REDUCE(I2:K2,
    UNIQUE(
        MONTH(
            B3:B20
        )
    ),
    LAMBDA(a,
    v,VSTACK(a,
    LET(b,
    B3:B20,
    c,
    C3:C20,
    d,
    --(v&-2024),i,
    UNIQUE(
        c
    ),
    w,
    SUMIFS(
        D3:D20,
        c,
        i,
        b,
        ">="&d,
        b,
        "<"&
        EDATE(
            d,
            1
        )
    ),
    r,
    IFNA(
        SORT(
            HSTACK(
                v,
                i,
                w/SUM(
                    w
                )
            ),
            3,
            -1
        ),
        v
    ),VSTACK(
    TAKE(
        r,
        2
    ),
    HSTACK(
        v,
        "Other",
        SUM(
            DROP(
                r,
                2,
                1
            )
        )
    )
)))))
Excel solution 4 for Top Products!, proposed by Oscar Mendez Roca Farell:
=LET(
    m,
     MONTH(
         B3:B20
     ),
     REDUCE(
         I2:K2,
          UNIQUE(
              m
          ),
          LAMBDA(
              i,
               x,
               LET(
                   f,
                    FILTER(
                        C3:D20,
                         m=x
                    ),
                    p,
                    TAKE(
                        f,
                         ,
                         1
                    ),
                    u,
                    TOROW(
                        UNIQUE(
                            p
                        )
                    ),
                    m,
                    MMULT(
                        TOROW(
                            DROP(
                                f,
                                 ,
                                1
                            )
                        ),
                         N(
                             p=u
                         )
                    ),
                    k,
                    LARGE(
                        m,
                         {1,
                         2}
                    ),
                    s,
                    k/SUM(
              m
          ),
                    VSTACK(
                        i,
                         IFNA(
                             HSTACK(
                                 x,
                                  TRANSPOSE(
                                      IFNA(
                                          VSTACK(
                                              XLOOKUP(
                                                  k,
                                                   m,
                                                   u
                                              ),
                                               HSTACK(
                                                   s,
                                                    1-SUM(
                                                        s
                                                    )
                                               )
                                          ),
                                           "Other"
                                      )
                                  )
                             ),
                              x
                         )
                    )
               )
          )
     )
)
Excel solution 5 for Top Products!, proposed by Julian Poeltl:
=LET(
    D,
    B3:B20,
    P,
    C3:C20,
    Q,
    D3:D20,
    M,
    MONTH(
        D
    ),
    C,
    UNIQUE(
        M&P
    ),
    S,
    MAP(
        C,
        LAMBDA(
            A,
            SUM(
                FILTER(
                    Q,
                    M&P=A
                )
            )
        )
    ),
    REDUCE(
        HSTACK(
            "Month",
            "Product",
            "% of Month sales"
        ),
        UNIQUE(
            M
        ),
        LAMBDA(
            A,
            B,
            VSTACK(
                A,
                LET(
                    F,
                    FILTER(
                        HSTACK(
                            C,
                            S
                        ),
                        --LEFT(
                            C
                        )=B
                    ),
                    S,
                    SORT(
                        F,
                        2,
                        -1
                    ),
                    T,
                    TAKE(
                        S,
                        2,
                        1
                    ),
                    Su,
                    SUM(
                        TAKE(
                            S,
                            ,
                            -1
                        )
                    ),
                    P,
                    TAKE(
                            S,
                            ,
                            -1
                        )/Su,
                    VSTACK(
                        HSTACK(
                            --LEFT(
                                T
                            ),
                            RIGHT(
                                T
                            ),
                            TAKE(
                                P,
                                2
                            )
                        ),
                        HSTACK(
                            B,
                            "Other",
                            SUM(
                                DROP(
                                P,
                                2
                            )
                            )
                        )
                    )
                )
            )
        )
    )
)
Excel solution 6 for Top Products!, proposed by Kris Jaganah:
=LET(
    a,
    MONTH(
        B3:B20
    ),
    b,
    C3:C20,
    c,
    D3:D20,
    d,
    PIVOTBY(
        b,
        a,
        c,
        PERCENTOF
    ),
    e,
    INDEX(
        d,
        MATCH(
            b,
            TAKE(
                d,
                ,
                1
            ),
            0
        ),
        MATCH(
            a,
            TAKE(
                d,
                1
            ),
            0
        )
    ),
    f,
    SORT(
        HSTACK(
            a,
            b,
            e
        ),
        {1,
        3},
        {1,
        -1}
    ),
    g,
    IF(
        SEQUENCE(
            ROWS(
                a
            )
        )-XMATCH(
            a,
            a
        )>1,
        "Other",
        CHOOSECOLS(
            f,
            2
        )
    ),
    h,
    GROUPBY(
        HSTACK(
            TAKE(
                f,
                ,
                1
            ),
            g
        ),
        TAKE(
            f,
            ,
            -1
        ),
        SUM,
        0,
        0
    ),
    h
)
Excel solution 7 for Top Products!, proposed by John Jairo Vergara Domínguez:
=LET(
    m,
    MONTH(
        B3:B20
    ),
    v,
    VSTACK,
    h,
    HSTACK,
    REDUCE(
        I2:K2,
        UNIQUE(
            m
        ),
        LAMBDA(
            a,
            x,
            LET(
                g,
                GROUPBY(
                    C3:C20,
                    D3:D20,
                    SUM,
                    ,
                    0,
                    -2,
                    m=x
                ),
                i,
                TAKE(
                    IFERROR(
                        g/SUM(
                            g
                        ),
                        g
                    ),
                    2
                ),
                v(
                    a,
                    h(
                        IF(
                            {1;1;1},
                            x
                        ),
                        v(
                            i,
                            h(
                                "Other",
                                1-SUM(
                                    i
                                )
                            )
                        )
                    )
                )
            )
        )
    )
)
Excel solution 8 for Top Products!, proposed by Sunny Baggu:
=LET(     _d,
     MONTH(
         B3:B20
     ),     _ud,
     UNIQUE(
         _d
     ),     REDUCE(          {"Month",
          "Product",
          "% of Month sales"},          _ud,          LAMBDA(
              x,
               y,
              
               VSTACK(
                   
                    x,
                   
                    LET(
                        
                         _a,
                         FILTER(
                             C3:D20,
                              _d = y
                         ),
                        
                         _ua,
                         UNIQUE(
                             TAKE(
                                 _a,
                                  ,
                                  1
                             )
                         ),
                        
                         _ub,
                         MAP(
                             _ua,
                              LAMBDA(
                                  a,
                                   SUM(
                                       FILTER(
                                           TAKE(
                                               _a,
                                                ,
                                                -1
                                           ),
                                            TAKE(
                                 _a,
                                  ,
                                  1
                             ) = a
                                       )
                                   )
                              )
                         ),
                        
                         _p,
                         ROUND(
                             100 * _ub / SUM(
                                 _ub
                             ),
                              0
                         ),
                        
                         _g,
                         SORT(
                             HSTACK(
                                 _ua,
                                  _p
                             ),
                              2,
                              -1
                         ),
                        
                         _f,
                         VSTACK(
                             TAKE(
                                 _g,
                                  2
                             ),
                              HSTACK(
                                  "Other",
                                   SUM(
                                       DROP(
                                           _g,
                                            2,
                                            1
                                       )
                                   )
                              )
                         ),
                        
                         IFNA(
                             HSTACK(
                                 y,
                                  _f
                             ),
                              y
                         )
                         
                    )
                    
               )
               
          )     ))
Excel solution 9 for Top Products!, proposed by Asheesh Pahwa:
=LET(
    dt,
    B3:B20,
    p,
    C3:D20,
    m,
    MONTH(
        dt
    ),
    u,
    UNIQUE(
        m
    ),
    r,
    REDUCE(
        "",
        u,
        LAMBDA(
            x,
            y,
            VSTACK(
                x,
                LET(
                    f,
                    FILTER(
                        p,
                        m=y
                    ),
                    s,
                    SUM(
                        TAKE(
                            f,
                            ,
                            -1
                        )
                    ),
                    t,
                    TAKE(
                        f,
                        ,
                        1
                    ),
                    un,
                    UNIQUE(
                        t
                    ),
                    d,
                    DROP(
                        REDUCE(
                            "",
                            un,
                            LAMBDA(
                                a,
                                v,
                                VSTACK(
                                    a,
                                    LET(
                                        r,
                                        ROUND(
                                            SUM(
                                                FILTER(
                                                    TAKE(
                            f,
                            ,
                            -1
                        ),
                                                    t=v
                                                )
                                            )/s*100,
                                            0
                                        ),
                                        HSTACK(
                                            v,
                                            r
                                        )
                                    )
                                )
                            )
                        ),
                        1
                    ),
                    tkt,
                    TAKE(
                        SORTBY(
                            d,
                            TAKE(
                                d,
                                ,
                                -1
                            ),
                            -1
                        ),
                        2
                    ),
                    IFNA(
                        HSTACK(
                            y,
                            VSTACK(
                                tkt,
                                HSTACK(
                                    "Others",
                                    100-SUM(
                                        TAKE(
                                            tkt,
                                            ,
                                            -1
                                        )
                                    )
                                )
                            )
                        ),
                        y
                    )
                )
            )
        )
    ),
    DROP(
        r,
        1
    )
)

 

Excel solution 10 for Top Products!, proposed by ferhat CK:
=REDUCE(I2:K2,
    SEQU
Excel solution 10 for Top Products!, proposed by ferhat CK:

Leave a Reply