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

The Power BI Data Visualization World Championships is back! Get ahead of the game and start preparing now! Learn more

Reply
rob_vander2
Helper II
Helper II

complex power query transformation help

Hi All,

 

I have below dataset and required output as attached. I need to rolling quarterly  figure for Value for each combination of ID,Category,Sub Category and Type. For example, for Month Dec-24, combination of ID,Category,Sub Category and Type, I need to go back Oct-24,Nov-24 & Dec-24 and aggregate the Value.

 

IDCategorySub CategoryTypeMonthValue
1AAAT1Sep-24100
1AAAT1Oct-2450
1AABT2Nov-24100
1AABT2Dec-2490
      
1AAAT1Sep-24100
1AAAT1Oct-2450
2AABT2Nov-24100
2AABT2Dec-2490
      
1AAAT1Sep-24100
1ABBT2Oct-2450
2AAAT1Nov-24100
2AAAT1Dec-2490

 

Screenshot 2025-02-26 at 10.53.56.png

2 ACCEPTED SOLUTIONS
Akash_Varuna
Super User
Super User

Hi @rob_vander2 Could you try this please  After Loading the data to Power Query

  • Sort the Data:

    • Sort the table by ID, Category, Sub Category, Type, and Month in ascending order.

  • Create a Custom Column for Rolling Total:

    • Go to Add Column > Custom Column:
      List.Sum(
      Table.SelectRows(
      #"Previous Step",
      (x) =>
      x[ID] = [ID] and
      x[Category] = [Category] and
      x[Sub Category] = [Sub Category] and
      x[Type] = [Type] and
      Date.FromText(x[Month]) <= Date.FromText([Month]) and
      Date.FromText(x[Month]) >= Date.AddMonths(Date.FromText([Month]), -2)
      )[Value]
      )
      Rename the custom column

      If this post helped please do give a kudos and accept this as a solution

      Thanks In Advance 

View solution in original post

I don't know, you have to test it 😉

 

You can also try this one (I've just added one 0 as 4th argument of inner Table.Group), but you can notice the speed difference. This will work if your data is sturcutred as your sample.

 

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMlTSUXJ0BBFAHALiBacW6BqZABmGBgZKsTrYlPgnl0CUmKKpcAKpMAISfvllOAyBK3FJTYYosYSoUAAyMTF2B5DhRiPCbsRUQn03OiEbj9ONcENwuxGuBMWNsQA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [ID = _t, Category = _t, #"Sub Category" = _t, Type = _t, Month = _t, Value = _t]),
    // You can delete this step when applying on real data.
    ReplacedBlanks = Table.TransformColumns(Source, {}, each if Text.Trim(_) = "" then null else _),
    ChangedType = Table.TransformColumnTypes(ReplacedBlanks,{{"Value", Int64.Type}}),
    TransformedValue = Table.Combine(Table.Group(ChangedType, "ID", {{"T", each Table.Combine(Table.Group(_, {"ID", "Category", "Sub Category", "Type"}, {{"T2", (x)=> if x{0}[ID] = null then x else let a = Table.ToRecords(x) in Table.FromRecords(List.RemoveLastN(a, 1) & {List.Last(a) & [Value = List.Sum(x[Value])]}) , type table}}, 0)[T2]), type table}}, 0, (x,y)=> Byte.From(y is null))[T])
in
    TransformedValue

 


Note: Check this link to learn how to use my query.
Check this link if you don't know how to provide sample data.

View solution in original post

7 REPLIES 7
dufoq3
Super User
Super User

Hi @rob_vander2, check this:

 

Output

dufoq3_0-1740596351264.png

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMlTSUXJ0BBFAHALiBacW6BqZABmGBgZKsTrYlPgnl0CUmKKpcAKpMAISfvllOAyBK3FJTYYosYSoUAAyMTF2B5DhRiPCbsRUQn03OiEbj9ONcENwuxGuBMWNsQA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [ID = _t, Category = _t, #"Sub Category" = _t, Type = _t, Month = _t, Value = _t]),
    // You can delete this step when applying on real data.
    ReplacedBlanks = Table.TransformColumns(Source, {}, each if Text.Trim(_) = "" then null else _),
    ChangedType = Table.TransformColumnTypes(ReplacedBlanks,{{"Value", Int64.Type}}),
    TransformedValue = Table.Combine(Table.Group(ChangedType, "ID", {{"T", each Table.Combine(Table.Group(_, {"ID", "Category", "Sub Category", "Type"}, {{"T2", (x)=> if x{0}[ID] = null then x else let a = Table.ToRecords(x) in Table.FromRecords(List.RemoveLastN(a, 1) & {List.Last(a) & [Value = List.Sum(x[Value])]}) , type table}})[T2]), type table}}, 0, (x,y)=> Byte.From(y is null))[T])
in
    TransformedValue

Note: Check this link to learn how to use my query.
Check this link if you don't know how to provide sample data.

@dufoq3  Could you please explain how TransformedValue step works?

TransformedValue step explanation in steps:

  1. Group rows by "ID"
  2. Inner group rows by columns: "ID", "Category", "Sub Category", "Type" 
  3. Replace last [Value] with sum of [Value] column (for this inner group step)
  4. Combine Inner group to 1 table
  5. Combine Outer group to 1 table

Note: Check this link to learn how to use my query.
Check this link if you don't know how to provide sample data.

@dufoq3  How performant it will be? I have millions of data.

I don't know, you have to test it 😉

 

You can also try this one (I've just added one 0 as 4th argument of inner Table.Group), but you can notice the speed difference. This will work if your data is sturcutred as your sample.

 

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMlTSUXJ0BBFAHALiBacW6BqZABmGBgZKsTrYlPgnl0CUmKKpcAKpMAISfvllOAyBK3FJTYYosYSoUAAyMTF2B5DhRiPCbsRUQn03OiEbj9ONcENwuxGuBMWNsQA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [ID = _t, Category = _t, #"Sub Category" = _t, Type = _t, Month = _t, Value = _t]),
    // You can delete this step when applying on real data.
    ReplacedBlanks = Table.TransformColumns(Source, {}, each if Text.Trim(_) = "" then null else _),
    ChangedType = Table.TransformColumnTypes(ReplacedBlanks,{{"Value", Int64.Type}}),
    TransformedValue = Table.Combine(Table.Group(ChangedType, "ID", {{"T", each Table.Combine(Table.Group(_, {"ID", "Category", "Sub Category", "Type"}, {{"T2", (x)=> if x{0}[ID] = null then x else let a = Table.ToRecords(x) in Table.FromRecords(List.RemoveLastN(a, 1) & {List.Last(a) & [Value = List.Sum(x[Value])]}) , type table}}, 0)[T2]), type table}}, 0, (x,y)=> Byte.From(y is null))[T])
in
    TransformedValue

 


Note: Check this link to learn how to use my query.
Check this link if you don't know how to provide sample data.

Akash_Varuna
Super User
Super User

Hi @rob_vander2 Could you try this please  After Loading the data to Power Query

  • Sort the Data:

    • Sort the table by ID, Category, Sub Category, Type, and Month in ascending order.

  • Create a Custom Column for Rolling Total:

    • Go to Add Column > Custom Column:
      List.Sum(
      Table.SelectRows(
      #"Previous Step",
      (x) =>
      x[ID] = [ID] and
      x[Category] = [Category] and
      x[Sub Category] = [Sub Category] and
      x[Type] = [Type] and
      Date.FromText(x[Month]) <= Date.FromText([Month]) and
      Date.FromText(x[Month]) >= Date.AddMonths(Date.FromText([Month]), -2)
      )[Value]
      )
      Rename the custom column

      If this post helped please do give a kudos and accept this as a solution

      Thanks In Advance 

@Akash_Varuna  I am not sure how to apply this. Could you share PBIX file?

Helpful resources

Announcements
Power BI DataViz World Championships

Power BI Dataviz World Championships

The Power BI Data Visualization World Championships is back! Get ahead of the game and start preparing now!

December 2025 Power BI Update Carousel

Power BI Monthly Update - December 2025

Check out the December 2025 Power BI Holiday Recap!

FabCon Atlanta 2026 carousel

FabCon Atlanta 2026

Join us at FabCon Atlanta, March 16-20, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM.

Top Solution Authors