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

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

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
Fabric Data Days Carousel

Fabric Data Days

Advance your Data & AI career with 50 days of live learning, contests, hands-on challenges, study groups & certifications and more!

October Power BI Update Carousel

Power BI Monthly Update - October 2025

Check out the October 2025 Power BI update to learn about new features.

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 Kudoed Authors