Divide the data into groups sequentially such that sum of Sale in a group should not exceed 20 and should be as close to 20 as possible in a group. Example – For first 4 rows, 7+5+7=19 and next entry is 8. Hence, Group1 will be 7+5+7 only as 7+5+7+8 will exceed 20, hence group 2 will start from 8. Note – The maximum value Sale column can contain is 20.
📌 Challenge Details and Links
ExcelBI Power Query Challenge Number: 119
Challenge Difficulty: ⭐️⭐️⭐️
📥Download Sample File
📥Link to the solutions on LinkedIn
Solving the challenge of Group Data Within Sale Limit with Power Query
Power Query solution 1 for Group Data Within Sale Limit, proposed by Bo Rydobon 🇹🇭:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
Group = List.Transform(
List.Accumulate(
List.Zip(
{
List.Accumulate(
Source[Sale],
{},
(s, v) =>
let
a = List.Last(s, 0),
b = Number.From(a + v < 21) * a + v
in
s & {b}
),
Source[Sale]
}
),
{},
(g, l) => g & {List.Last(g, 0) + Number.From(l{0} = l{1})}
),
each "Group" & Text.From(_)
),
Ans = Table.FromColumns(Table.ToColumns(Source) & {Group}, Table.ColumnNames(Source) & {"Group"})
in
Ans
Power Query solution 2 for Group Data Within Sale Limit, proposed by Zoran Milokanović:
let
Source = Excel.CurrentWorkbook(){[Name = "Input"]}[Content],
G = "Group",
I = each G & Text.From(Number.From(Text.End(_, Text.Length(_) - 5)) + 1),
S = Table.FromRows(
List.Accumulate(
Table.ToRows(Source),
{},
(s, c) =>
s
& {
let
l = List.Last(s, {"", 0, G & "1"}),
g = l{2},
m = List.Sum(List.Zip(List.Select(s, each _{2} = g)){1}? ?? {0})
in
c & {if m + c{1} <= 20 then g else I(g)}
}
),
Table.ColumnNames(Source) & {G}
)
in
S
Power Query solution 3 for Group Data Within Sale Limit, proposed by Kris Jaganah:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
Index = Table.AddIndexColumn(Source, "Index", 1, 1, Int64.Type),
Cumul20 = Table.AddColumn(
Index,
"First20",
each List.Accumulate(
List.Range(Index[Sale], 0, [Index]),
0,
(P, C) => if P + C > 20 then C else P + C
)
),
Group = Table.AddColumn(
Cumul20,
"Group",
each
let
a = Table.AddColumn(Cumul20, "Custom", each if [Sale] = [First20] then 1 else 0)[Custom],
b = List.Accumulate(List.Range(a, 0, [Index]), 0, (X, Y) => X + Y),
c = "Group" & Text.From(b)
in
c
),
Remove = Table.RemoveColumns(Group, {"Index", "First20"})
in
Remove
Power Query solution 4 for Group Data Within Sale Limit, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
Grupos = List.Transform(
List.Skip(
List.Generate(
() => [x = 0, y = 0, z = 1],
each [x] <= Table.RowCount(Source),
each [
y = if [y] + Source[Sale]{[x]} > 20 then Source[Sale]{[x]} else [y] + Source[Sale]{[x]},
z = if [y] + Source[Sale]{[x]} > 20 then [z] + 1 else [z],
x = [x] + 1
],
each [z]
)
),
each "Group" & Text.From(_)
),
Sol = Table.FromColumns(Table.ToColumns(Source) & {Grupos}, Table.ColumnNames(Source) & {"Group"})
in
Sol
Power Query solution 5 for Group Data Within Sale Limit, proposed by Alexis Olson:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
Table1 = Table.TransformColumnTypes(Source, {{"Name", type text}, {"Sale", Int64.Type}}),
Sales = Table1[Sale],
GroupCol = List.Generate(
() => [i = 0, sum = Sales{0}, group = 1],
each [i] < List.Count(Sales),
each [
i = [i] + 1,
sum = if [sum] + Sales{i} > 20 then Sales{i} else [sum] + Sales{i},
group = if [sum] + Sales{i} > 20 then [group] + 1 else [group]
],
each "Group" & Number.ToText([group])
),
AddCol = Table.FromColumns(Table.ToColumns(Table1) & {GroupCol}, {"Name", "Sale", "Group"})
in
AddCol
Power Query solution 6 for Group Data Within Sale Limit, proposed by Eric Laforce:
let
Source = Excel.CurrentWorkbook(){[Name = "tData119"]}[Content],
AddGroup = List.Accumulate(
Table.ToRows(Source),
[t = 0, g = 1, r = {}],
(s, c) =>
let
_t = s[t] + c{1}
in
if (_t <= 20) then
[t = _t, g = s[g], r = s[r] & {c & {s[g]}}]
else
[t = c{1}, g = s[g] + 1, r = s[r] & {c & {s[g] + 1}}]
)[r],
ToTable = Table.FromRows(AddGroup, Table.ColumnNames(Source) & {"Group"}),
TransformGroup = Table.TransformColumns(ToTable, {"Group", each "Group" & Text.From(_)})
in
TransformGroup
Power Query solution 7 for Group Data Within Sale Limit, proposed by Sandeep Marwal:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
Custom1 = List.Skip(
List.Accumulate(
Source[Sale],
{0},
(c, v) => if List.Last(c) + v <= 20 then c & {v + List.Last(c)} else c & {v}
)
),
Custom2 = Table.FromColumns(Table.ToColumns(Source) & {Custom1}),
#"Added Conditional Column" = Table.AddColumn(
Custom2,
"Custom",
each if [Column2] = [Column3] then "G" else null
),
#"Grouped Rows" = Table.Group(
#"Added Conditional Column",
{"Custom"},
{
{
"Count",
each _,
type table [Column1 = text, Column2 = number, Column3 = number, Custom = nullable text]
}
},
0,
(c, n) => Number.From(n[Custom] = "G")
),
#"Added Index" = Table.AddIndexColumn(#"Grouped Rows", "Index", 1, 1, Int64.Type),
#"Expanded Count" = Table.ExpandTableColumn(
#"Added Index",
"Count",
{"Column1", "Column2", "Column3", "Custom"},
{"Column1", "Column2", "Column3", "Custom.1"}
),
#"Removed Other Columns" = Table.SelectColumns(#"Expanded Count", {"Column1", "Column2", "Index"}),
#"Renamed Columns" = Table.RenameColumns(
#"Removed Other Columns",
{{"Column1", "Name"}, {"Column2", "Sale"}, {"Index", "Group"}}
),
#"Added Prefix" = Table.TransformColumns(
#"Renamed Columns",
{{"Group", each "Group" & Text.From(_, "en-IN"), type text}}
)
in
#"Added Prefix"
Solving the challenge of Group Data Within Sale Limit with Excel
Excel solution 1 for Group Data Within Sale Limit, proposed by Bo Rydobon 🇹🇭:
=HSTACK(A1:B26,VSTACK("Group","Group"&SCAN(0,SCAN(,B2:B26,LAMBDA(a,v,(a+v<21)*a+v))=B2:B26,LAMBDA(a,v,a+v))))
Excel solution 2 for Group Data Within Sale Limit, proposed by محمد حلمي:
=LET(
e,REDUCE(0,A2:A20,LAMBDA(a,v,LET(
d,TAKE(v:B20,1),VSTACK(a,IF(d,TAKE(a,-1)+d,d))))),
x,FILTER(e,TAKE(e,,1)*(VSTACK(DROP(e,1,-1)=0,1))),
i,"Group",VSTACK(HSTACK(i,A1:B1),
HSTACK(i&SEQUENCE(ROWS(x)),x)))
Excel solution 3 for Group Data Within Sale Limit, proposed by محمد حلمي:
=HSTACK(A1:B26,"Group"&VSTACK("",SCAN(0,B2:B26=SCAN(0,B2:B26,LAMBDA(a,d,IF(a+d<21,a+d,d))),LAMBDA(a,d,a+d))))
Excel solution 4 for Group Data Within Sale Limit, proposed by محمد حلمي:
="Group"&
REDUCE("",
B2:B26=REDUCE(,B2:B26,LAMBDA(a,d,VSTACK(a,
IF(TAKE(a,-1)+d<21,TAKE(a,-1)+d,d)))),
LAMBDA(a,d,VSTACK(a,TAKE(N(a),-1)+d)))
Excel solution 5 for Group Data Within Sale Limit, proposed by محمد حلمي:
="Group"&
SCAN(0,
B2:B26=SCAN(0,B2:B26,LAMBDA(a,d,IF(a+d<21,a+d,d))),
LAMBDA(a,d,a+d))
Excel solution 6 for Group Data Within Sale Limit, proposed by محمد حلمي:
="Group"&
SCAN(0,B2:B26=
SCAN(0,E2:E26,LAMBDA(a,d,IF(a+d<21,a+d,d))),
LAMBDA(a,d,a+d))
Excel solution 7 for Group Data Within Sale Limit, proposed by محمد حلمي:
="Group"&SCAN(0,B2:B26=SCAN(0,E2:E26,LAMBDA(a,d,IF(a+d<21,a+d,d))),LAMBDA(a,d,a+d))
Excel solution 8 for Group Data Within Sale Limit, proposed by Kris Jaganah:
=LET(a,A2:A26,b,B2:B26,VSTACK({"Name","Sale","Group"},HSTACK(a,b,"Group"&SCAN(0,SCAN(0,b,LAMBDA(x,y,IF(y+x>20,y,y+x)))=b,LAMBDA(v,w,IF(w,1+v,v))))))
Excel solution 9 for Group Data Within Sale Limit, proposed by Oscar Mendez Roca Farell:
=LET(_m,MAP(B2:B26, LAMBDA(b, SUM(B2:b))), HSTACK(A1:B26, VSTACK("Group","Group"&1+INT(MROUND(_m, 10)/20))))
Excel solution 10 for Group Data Within Sale Limit, proposed by Sunny Baggu:
=LET(
_sale, B2:B26,
_sumsale, SCAN(
0,
_sale,
LAMBDA(a, v, IF(a + v <= 21, a + v, v))
),
HSTACK(
A2:B26,
"Group" & SCAN(0, _sale = _sumsale, LAMBDA(a, v, a + v))
)
)
Excel solution 11 for Group Data Within Sale Limit, proposed by Anup Kumar:
=HSTACK(A2:B26,"Group"&LET(
sale,B2:B26,
sm, SCAN(0,sale,LAMBDA(x,y,IF(x+y>20,y,x+y))),
SCAN(0,sm-sale,LAMBDA(a,b,IF(b,a,a+1))))
)
Solving the challenge of Group Data Within Sale Limit with Python in Excel
Python in Excel solution 1 for Group Data Within Sale Limit, proposed by Bo Rydobon 🇹🇭:
df =xl("A1:B26", headers = True)
c,g =0,0
df['Group']=['Group'+str(g:=g+(c==s)) for s in df.Sale if (c:=(c+s<21)*c+s)]
df
Python in Excel solution 2 for Group Data Within Sale Limit, proposed by 🇰🇷 Taeyong Shin:
df = xl("A1:B26", headers=True)
def group_num(sales):
new_list = list()
cumsum = 0
gn = 1
for n in sales:
cumsum += n
if cumsum > 20:
gn += 1
cumsum = n
new_list.append(f'Group{gn}')
return new_list
df.assign(Group = group_num(df['Sale']))
&&&
