Starting December 3, join live sessions with database experts and the Microsoft product team to learn just how easy it is to get started
Learn moreShape the future of the Fabric Community! Your insights matter. That’s why we created a quick survey to learn about your experience finding answers to technical questions. Take survey.
Dear All,
Asking for your kind help. I'd like to collect values from a column (named strawberry) that is missaligned (first, it is in the 2nd column, than it is in the 3rd column and than in the 4th column) in the dataset.
Input data is in the first 4 columns on the left hand side, expected output in the last column in the example table below.
It's always the strawberry, and there's always a header (=new items have arrived) before any alignment change.
new | items | have | arrived | |||
apple | strawberry | strawberry | ||||
4 | 6 | 6 | ||||
1 | 2 | 2 | ||||
3 | 1 | 1 | ||||
new | items | have | arrived | |||
apple | orange | strawberry | ||||
1 | 2 | 1 | 1 | |||
2 | 2 | 3 | 3 | |||
new | items | have | arrived | |||
apple | orange | pear | strawberry | |||
3 | 1 | 5 | 1 | 1 | ||
1 | 2 | 1 | 4 | 4 | ||
1 | 3 | 2 | 7 | 7 | ||
2 | 4 | 6 | 3 | 3 |
As there are hundreds of thousands of rows, power query is the preferred way.
How can I achieve this?
Thanks in advance.
Solved! Go to Solution.
Hi @psvdr, another solution here:
Result
v1 (group transformation based on List.PositionOf)
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WykstV9JRyixJzS0G0hmJZalAKrGoKLMsNUUpVidaKbGgIAckVlxSlFielFpUVAnkKIAxSNoEyDJDETEEsoxQRIyBLEMUEaJtzS9KzEvHYj2yRYZwESOoiDEFFhWkJhah2ofsBVMwjW67CVzEGCpqDncPLICMlWJjAQ==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Column1 = _t, Column2 = _t, Column3 = _t, Column4 = _t]),
GroupedRows = Table.Group(Source, {"Column1"}, {{"All", each
[ a = List.Transform(Table.ToColumns(_), (x)=> List.Contains(x, "strawberry")),
b = List.PositionOf(a, true),
c = Table.AddColumn(_, "strawberry", (x)=> if x[Column1] = "new" then null else Record.ToList(x){b}, type text)
][c], type table}},
GroupKind.Local, (s,c)=> Byte.From(c[Column1] = "new") ),
CombinedAll = Table.Combine(GroupedRows[All])
in
CombinedAll
v2 (group transformation based on List.TransformMany)
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WykstV9JRyixJzS0G0hmJZalAKrGoKLMsNUUpVidaKbGgIAckVlxSlFielFpUVAnkKIAxSNoEyDJDETEEsoxQRIyBLEMUEaJtzS9KzEvHYj2yRYZwESOoiDEFFhWkJhah2ofsBVMwjW67CVzEGCpqDncPLICMlWJjAQ==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Column1 = _t, Column2 = _t, Column3 = _t, Column4 = _t]),
AddedIndex = Table.AddIndexColumn(Source, "Index", 0, 1, Int64.Type),
Ad_GroupHelper = Table.AddColumn(AddedIndex, "GroupHelper", each if [Column1] = "new" then [Index] else null, Int64.Type),
FilledDown = Table.FillDown(Ad_GroupHelper,{"GroupHelper"}),
GroupedRows = Table.Group(FilledDown, {"GroupHelper"}, {{"All", each
[ a = Table.ToColumns(_),
b = List.TransformMany(a,
(y)=> {List.Contains(y, "strawberry")},
(x,y)=> List.Select(x, (w)=> y) ),
c = {null} & List.Skip(List.Combine(b)),
d = Table.FromColumns(a & {c})
][d], type table}}),
CombinedAll = Table.Combine(GroupedRows[All]),
RemovedColumns = Table.RemoveColumns(CombinedAll,{"Column5", "Column6"})
in
RemovedColumns
Another solution without Table.Group
One item
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WykstV9JRyixJzS0G0hmJZalAKrGoKLMsNUUpVidaKbGgIAckVlxSlFielFpUVAnkKIAxSNoEyDJDETEEsoxQRIyBLEMUEaJtzS9KzEvHYj2yRYZwESOoiDEFFhWkJhah2ofsBVMwjW67CVzEGCpqDncPLICMlWJjAQ==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Column1 = _t, Column2 = _t, Column3 = _t, Column4 = _t]),
PositionOf = Table.AddColumn(Source, "strawberry",
each List.PositionOf(Record.ToList(_), "strawberry")),
Replace_Position = Table.ReplaceValue(PositionOf, -1, null, Replacer.ReplaceValue, {"strawberry"}),
FillDown = Table.FillDown(Replace_Position, {"strawberry"}),
Replace_Value = Table.ReplaceValue(FillDown, each Record.ToList(_),
each null, (p,r,z)=> try Number.From(r{p}) otherwise null, {"strawberry"})
in
Replace_Value
Many items
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WykstV9JRyixJzS0G0hmJZalAKrGoKLMsNUUpVidaKbGgIAckVlxSlFielFpUVAnkKIAxSNoEyDJDETEEsoxQRIyBLEMUEaJtzS9KzEvHYj2yRYZwESOoiDEFFhWkJhah2ofsBVMwjW67CVzEGCpqDncPLICMlWJjAQ==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Column1 = _t, Column2 = _t, Column3 = _t, Column4 = _t]),
My_List = List.Buffer({"strawberry","pear","apple","orange"}),
PositionOf = Table.AddColumn(Source, "My_List",
(x) => List.ReplaceValue(List.Transform(My_List,
each List.PositionOf(Record.ToList(x), _)), -1, null, Replacer.ReplaceValue)),
Replace_Position = Table.ReplaceValue(PositionOf, each List.NonNullCount([My_List]), null,
(x,y,z) => if y>0 then x else z, {"My_List"}),
FillDown = Table.FillDown(Replace_Position, {"My_List"}),
Replace_Value = Table.ReplaceValue(FillDown, each Record.ToList(_), each null,
(p,r,z)=> Table.FromRows({List.Transform(p ?? List.Repeat({null},List.Count(My_List)),
each try Number.From(r{_}) otherwise null)}, My_List), {"My_List"}),
Expand = Table.ExpandTableColumn(Replace_Value, "My_List", My_List, My_List)
in
Expand
Stéphane
Hi @psvdr, another solution here:
Result
v1 (group transformation based on List.PositionOf)
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WykstV9JRyixJzS0G0hmJZalAKrGoKLMsNUUpVidaKbGgIAckVlxSlFielFpUVAnkKIAxSNoEyDJDETEEsoxQRIyBLEMUEaJtzS9KzEvHYj2yRYZwESOoiDEFFhWkJhah2ofsBVMwjW67CVzEGCpqDncPLICMlWJjAQ==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Column1 = _t, Column2 = _t, Column3 = _t, Column4 = _t]),
GroupedRows = Table.Group(Source, {"Column1"}, {{"All", each
[ a = List.Transform(Table.ToColumns(_), (x)=> List.Contains(x, "strawberry")),
b = List.PositionOf(a, true),
c = Table.AddColumn(_, "strawberry", (x)=> if x[Column1] = "new" then null else Record.ToList(x){b}, type text)
][c], type table}},
GroupKind.Local, (s,c)=> Byte.From(c[Column1] = "new") ),
CombinedAll = Table.Combine(GroupedRows[All])
in
CombinedAll
v2 (group transformation based on List.TransformMany)
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WykstV9JRyixJzS0G0hmJZalAKrGoKLMsNUUpVidaKbGgIAckVlxSlFielFpUVAnkKIAxSNoEyDJDETEEsoxQRIyBLEMUEaJtzS9KzEvHYj2yRYZwESOoiDEFFhWkJhah2ofsBVMwjW67CVzEGCpqDncPLICMlWJjAQ==", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Column1 = _t, Column2 = _t, Column3 = _t, Column4 = _t]),
AddedIndex = Table.AddIndexColumn(Source, "Index", 0, 1, Int64.Type),
Ad_GroupHelper = Table.AddColumn(AddedIndex, "GroupHelper", each if [Column1] = "new" then [Index] else null, Int64.Type),
FilledDown = Table.FillDown(Ad_GroupHelper,{"GroupHelper"}),
GroupedRows = Table.Group(FilledDown, {"GroupHelper"}, {{"All", each
[ a = Table.ToColumns(_),
b = List.TransformMany(a,
(y)=> {List.Contains(y, "strawberry")},
(x,y)=> List.Select(x, (w)=> y) ),
c = {null} & List.Skip(List.Combine(b)),
d = Table.FromColumns(a & {c})
][d], type table}}),
CombinedAll = Table.Combine(GroupedRows[All]),
RemovedColumns = Table.RemoveColumns(CombinedAll,{"Column5", "Column6"})
in
RemovedColumns
so excellent solution!
I duplicate your data in excel like this
and transform it as a table which name is "表1",then into power query.
the code like follow:
Hi @psvdr
I have some questions that
1.Is the data you have offered are in the same table? or they represent 3 tables?
2.Is the column name 'strawbeyy' or the strawbeyy just a value in a column?
Best Regards!
Yolo Zhu
User | Count |
---|---|
25 | |
13 | |
12 | |
11 | |
8 |
User | Count |
---|---|
44 | |
27 | |
21 | |
16 | |
12 |