Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.

Reply
carrl284
Frequent Visitor

Group rows only where end and start dates are consecutive

Hi

This is a sample of my data.  Can anyone show me how to combine the rows in power query but only where the dates are consecutive.

This table 

IdJobIdSiteIdPersonIdStartEnd
1234142512/05/201915/05/2019
1235142514/08/201923/09/2019
1236142512/12/201905/01/2020
1239142506/01/202027/01/2020
1240142528/01/202025/02/2020
1242142516/04/202015/05/2020

 

becomes this table

JobIdSiteIdPersonIdStartEnd
142512/05/201915/05/2019
142514/08/201923/09/2019
142512/12/201925/02/2020
142516/04/202015/05/2020

 

Many Thanks

3 ACCEPTED SOLUTIONS
Jimmy801
Community Champion
Community Champion

Hello @carrl284 

 

check out this approach. First a new column is added to check if the rows are connected. If there are connected null is written otherwise the prior added Index-value. After a fill-down is made and this data is used to group them. In the function of the group a min for start and a max for end is applied

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("bc/RCcAgDATQXfwWEs9odRZx/zUaSyNVCwY5eRyxNRcQxXkXdMaNNAKIE4FDHSHN0P3j0+GFuJhHJK6Lzz/9el6v5Rw0gM3X3XOeRF+uzQvvHuXrtR+Lx7GP9ot5++/w/QY=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Id = _t, JobId = _t, SiteId = _t, PersonId = _t, Start = _t, End = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Id", Int64.Type}, {"JobId", Int64.Type}, {"SiteId", Int64.Type}, {"PersonId", Int64.Type}, {"Start", type date}, {"End", type date}}),
    #"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 0, 1),
    AddGroupColumn = Table.AddColumn
    (
        #"Added Index",
        "Group",
        (row)=> try if Date.AddDays(row[Start],-1)= #"Added Index"{[Index = row[Index]-1]}[End] then null else row[Index] otherwise row[Index]
    ),
    #"Filled Down" = Table.FillDown(AddGroupColumn,{"Group"}),
    #"Grouped Rows" = Table.Group(#"Filled Down", {"JobId", "SiteId", "PersonId", "Group"}, {{"Start", each List.Min([Start]), type date}, {"End", each List.Max([End]), type date}}),
    #"Removed Columns" = Table.RemoveColumns(#"Grouped Rows",{"Group"})
in
    #"Removed Columns"

 

Copy paste this code to the advanced editor in a new blank query to see how the solution works.

If this post helps or solves your problem, please mark it as solution (to help other users find useful content and to acknowledge the work of users that helped you)
Kudoes are nice too

Have fun

Jimmy

View solution in original post

AlB
Super User
Super User

Hi @carrl284 

Place the following M code in a blank query to see the steps.

 

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("bc/RCcAgDATQXfwWEs9odRZx/zUaSyNVCwY5eRyxNRcQxXkXdMaNNAKIE4FDHSHN0P3j0+GFuJhHJK6Lzz/9el6v5Rw0gM3X3XOeRF+uzQvvHuXrtR+Lx7GP9ot5++/w/QY=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Id = _t, JobId = _t, SiteId = _t, PersonId = _t, Start = _t, End = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Id", Int64.Type}, {"JobId", Int64.Type}, {"SiteId", Int64.Type}, {"PersonId", Int64.Type}, {"Start", type date}, {"End", type date}}),

    #"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 0, 1, Int64.Type),
    #"Added Custom1" = Table.AddColumn(#"Added Index", "BlockStart", each let 
        diffNext_ = try Duration.Days(#"Changed Type"[Start]{[Index]+1} - #"Changed Type"[End]{[Index]}) otherwise -1,
        diffPrev_ = try Duration.Days(#"Changed Type"[Start]{[Index]} - #"Changed Type"[End]{[Index]-1}) otherwise -1
    in 
       if diffPrev_ = 1 then null else [Start], type date),
    #"Filled Down" = Table.FillDown(#"Added Custom1",{"BlockStart"}),
    #"Grouped Rows" = Table.Group(#"Filled Down", {"JobId", "SiteId", "PersonId", "BlockStart"}, {{"End", each List.Max([End]), type date }}
),
    #"Renamed Columns" = Table.RenameColumns(#"Grouped Rows",{{"BlockStart", "Start"}})
in
    #"Renamed Columns"

 

 

Please mark the question solved when done and consider giving a thumbs up if posts are helpful.

Contact me privately for support with any larger-scale BI needs, tutoring, etc.

Cheers 

SU18_powerbi_badge

View solution in original post

shaowu459
Resolver II
Resolver II

try this one, change Query3 to the right table name in you query.

 

let
    Source = Excel.CurrentWorkbook(){[Name="Query3"]}[Content],
    res = Table.FromRecords(List.Accumulate(Table.ToRecords(Source),{},(x,y)=>if List.Last(x)[End]?+#duration(1,0,0,0)=y[Start] then List.ReplaceRange(x,List.Count(x)-1,1,{List.Last(x)&[End=y[End]]}) else x&{y}))
in
    res

 

 1.png

View solution in original post

4 REPLIES 4
carrl284
Frequent Visitor

All 3 approaches worked a treat.  I don't know if I can mark them all as the solution but I tried all 3 and they all worked perfectly.  Thanks

shaowu459
Resolver II
Resolver II

try this one, change Query3 to the right table name in you query.

 

let
    Source = Excel.CurrentWorkbook(){[Name="Query3"]}[Content],
    res = Table.FromRecords(List.Accumulate(Table.ToRecords(Source),{},(x,y)=>if List.Last(x)[End]?+#duration(1,0,0,0)=y[Start] then List.ReplaceRange(x,List.Count(x)-1,1,{List.Last(x)&[End=y[End]]}) else x&{y}))
in
    res

 

 1.png

AlB
Super User
Super User

Hi @carrl284 

Place the following M code in a blank query to see the steps.

 

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("bc/RCcAgDATQXfwWEs9odRZx/zUaSyNVCwY5eRyxNRcQxXkXdMaNNAKIE4FDHSHN0P3j0+GFuJhHJK6Lzz/9el6v5Rw0gM3X3XOeRF+uzQvvHuXrtR+Lx7GP9ot5++/w/QY=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Id = _t, JobId = _t, SiteId = _t, PersonId = _t, Start = _t, End = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Id", Int64.Type}, {"JobId", Int64.Type}, {"SiteId", Int64.Type}, {"PersonId", Int64.Type}, {"Start", type date}, {"End", type date}}),

    #"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 0, 1, Int64.Type),
    #"Added Custom1" = Table.AddColumn(#"Added Index", "BlockStart", each let 
        diffNext_ = try Duration.Days(#"Changed Type"[Start]{[Index]+1} - #"Changed Type"[End]{[Index]}) otherwise -1,
        diffPrev_ = try Duration.Days(#"Changed Type"[Start]{[Index]} - #"Changed Type"[End]{[Index]-1}) otherwise -1
    in 
       if diffPrev_ = 1 then null else [Start], type date),
    #"Filled Down" = Table.FillDown(#"Added Custom1",{"BlockStart"}),
    #"Grouped Rows" = Table.Group(#"Filled Down", {"JobId", "SiteId", "PersonId", "BlockStart"}, {{"End", each List.Max([End]), type date }}
),
    #"Renamed Columns" = Table.RenameColumns(#"Grouped Rows",{{"BlockStart", "Start"}})
in
    #"Renamed Columns"

 

 

Please mark the question solved when done and consider giving a thumbs up if posts are helpful.

Contact me privately for support with any larger-scale BI needs, tutoring, etc.

Cheers 

SU18_powerbi_badge

Jimmy801
Community Champion
Community Champion

Hello @carrl284 

 

check out this approach. First a new column is added to check if the rows are connected. If there are connected null is written otherwise the prior added Index-value. After a fill-down is made and this data is used to group them. In the function of the group a min for start and a max for end is applied

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("bc/RCcAgDATQXfwWEs9odRZx/zUaSyNVCwY5eRyxNRcQxXkXdMaNNAKIE4FDHSHN0P3j0+GFuJhHJK6Lzz/9el6v5Rw0gM3X3XOeRF+uzQvvHuXrtR+Lx7GP9ot5++/w/QY=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Id = _t, JobId = _t, SiteId = _t, PersonId = _t, Start = _t, End = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Id", Int64.Type}, {"JobId", Int64.Type}, {"SiteId", Int64.Type}, {"PersonId", Int64.Type}, {"Start", type date}, {"End", type date}}),
    #"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 0, 1),
    AddGroupColumn = Table.AddColumn
    (
        #"Added Index",
        "Group",
        (row)=> try if Date.AddDays(row[Start],-1)= #"Added Index"{[Index = row[Index]-1]}[End] then null else row[Index] otherwise row[Index]
    ),
    #"Filled Down" = Table.FillDown(AddGroupColumn,{"Group"}),
    #"Grouped Rows" = Table.Group(#"Filled Down", {"JobId", "SiteId", "PersonId", "Group"}, {{"Start", each List.Min([Start]), type date}, {"End", each List.Max([End]), type date}}),
    #"Removed Columns" = Table.RemoveColumns(#"Grouped Rows",{"Group"})
in
    #"Removed Columns"

 

Copy paste this code to the advanced editor in a new blank query to see how the solution works.

If this post helps or solves your problem, please mark it as solution (to help other users find useful content and to acknowledge the work of users that helped you)
Kudoes are nice too

Have fun

Jimmy

Helpful resources

Announcements
Microsoft Fabric Learn Together

Microsoft Fabric Learn Together

Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.

April Fabric Community Update

Fabric Community Update - April 2024

Find out what's new and trending in the Fabric Community.

Top Solution Authors
Top Kudoed Authors