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

The Power BI DataViz World Championships are on! With four chances to enter, you could win a spot in the LIVE Grand Finale in Las Vegas. Show off your skills.

Reply
Anonymous
Not applicable

Last 12 Months Column in Power Query

Let's say I have this fake data:

 

Reference DateComponentMonthly Removals
09/01/2021A1
12/01/2021A2
03/01/2022A5
05/01/2022A0
04/01/2022B3
08/01/2022B1
10/01/2022B0
11/01/2022B2
05/01/2023B1

 

I need to create a column that will calculate the Last 12 Month removals for each reference date and component, for example:

 

Reference DateComponentMonthly RemovalsRemovals L12M
09/01/2021A11
12/01/2021A23
03/01/2022A58
05/01/2022A08
04/01/2022B33
08/01/2022B14
10/01/2022B04
11/01/2022B26
05/01/2023B11

 

I need to perform this in Power Query, because I need to merge it with another dataset.

 

I've been trying to "filter" (Table.SelectRows) the table based on the date and component, but I keep getting the cyclic reference error. Any idea on how I could approach this problem?

1 ACCEPTED SOLUTION
ppm1
Solution Sage
Solution Sage

Here's one way to do it in the query editor.  To see how it works, just create a blank query, open the Advanced Editor and replace the text there with the M code below.

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("Xc9LDsAgCATQu7A2cUBt7LK9hvH+1xA/qZbFhMVLBiiFcHuwFwiTo0fDI9UVYjEkmjAIYZEsSpo8KRnCpnjQO8q+wmyo74zzDBjCJjbU5/U/IxyF+ldt", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [#"Reference Date" = _t, Component = _t, #"Monthly Removals" = _t, #"Removals L12M" = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Reference Date", type date}, {"Component", type text}, {"Monthly Removals", Int64.Type}, {"Removals L12M", Int64.Type}}),
    #"Added Custom" = Table.AddColumn(#"Changed Type", "Custom", each let
thisdate = [Reference Date],
thiscomponent = [Component],
prev12mrows = Table.SelectRows(#"Changed Type", each ([Component] = thiscomponent and ([Reference Date] <= thisdate and [Reference Date] >= Date.AddMonths(thisdate, -12)))),
sum = List.Sum(prev12mrows[Monthly Removals])
in 
sum)
in
    #"Added Custom"

Pat

Microsoft Employee

View solution in original post

7 REPLIES 7
jnfl
New Member

I have a similar need, but can't seem to implement @ppm1 's code.  In power query, I need to create a new column (l12modap) that, for all ids with at least 12 months of dap data, will sum the last 12 months of said data. 

 

I have the first 4 columns and would like to see the 5th, ei.e., column E:

 

 ABCDE 
1iddatemodapl12modap 
210016/1/202210 <= 12 = (blank)
310017/1/202220 <= 12 = (blank)
410018/1/202231 <= 12 = (blank)
510019/1/202240 <= 12 = (blank)
6100110/1/202250 <= 12 = (blank)
7100111/1/202260 <= 12 = (blank)
8100112/1/202270 <= 12 = (blank)
910011/1/202380 <= 12 = (blank)
1010012/1/202390 <= 12 = (blank)
1110013/1/2023100 <= 12 = (blank)
1210014/1/2023110 <= 12 = (blank)
1310015/1/2023121 <= 12 = (blank)
1410016/1/20231302=SUM(D2:D13)
1510017/1/20231402=SUM(D3:D14)
1610018/1/20231502=SUM(D4:D15)
1710019/1/20231601=SUM(D5:D16)
18100110/1/20231701=SUM(D6:D17)
19100111/1/20231801=SUM(D7:D18)
20100112/1/20231901=SUM(D8:D19)
2110011/1/20242001=SUM(D9:D20)
2210012/1/20242101=SUM(D10:D21)
2310013/1/20242201=SUM(D11:D22)
2410014/1/20242301=SUM(D12:D23)
2510015/1/20242401=SUM(D13:D24)
2610016/1/20242500=SUM(D14:D25)
2710017/1/20242600=SUM(D15:D26)
2810025/1/201810 <= 12 = (blank)
2910026/1/201820 <= 12 = (blank)
3010027/1/201830 <= 12 = (blank)
3110028/1/201840 <= 12 = (blank)
3210029/1/201850 <= 12 = (blank)
33100210/1/201860 <= 12 = (blank)
34100211/1/201870 <= 12 = (blank)
35100212/1/201880 <= 12 = (blank)
3610021/1/201990 <= 12 = (blank)
3710022/1/2019101 <= 12 = (blank)
3810023/1/2019110 <= 12 = (blank)
3910024/1/2019121 <= 12 = (blank)
4010025/1/20191302=SUM(D28:D39)
4110026/1/20191402=SUM(D29:D40)
4210027/1/20191502=SUM(D30:D41)
43100312/1/202010 <= 12 = (blank)
4410031/1/202120 <= 12 = (blank)
4510032/1/202130 <= 12 = (blank)
4610033/1/202140 <= 12 = (blank)
4710034/1/202150 <= 12 = (blank)
4810035/1/202160 <= 12 = (blank)
4910036/1/202170 <= 12 = (blank)
5010037/1/202180 <= 12 = (blank)
5110038/1/202190 <= 12 = (blank)
5210039/1/2021100 <= 12 = (blank)
53100310/1/2021110 <= 12 = (blank)
54100311/1/2021121 <= 12 = (blank)
55100312/1/20211301=SUM(D43:D54)
5610031/1/20221401=SUM(D44:D55)
5710032/1/20221501=SUM(D45:D56)
5810033/1/20221601=SUM(D46:D57)
5910034/1/20221701=SUM(D47:D58)
6010035/1/20221801=SUM(D48:D59)

 

@ppm1, if you have any advice for this, that'd be terrific.  I should also say that when I tried to use your code before, I kept getting the error message that "We cannot convert a value of type Table to type list."  So you can see that I didn't get very far.  Thanks!

@jnfl This should have been created as a new topic with a reference to any previous similar solutions.
That being said, you can add a column to your existing query with the following code...

= Table.AddColumn(#"Changed Type", "last12dap", each if [mo] > 12 then List.Sum(Table.SelectRows(#"Changed Type", (x)=> x[id]= [id] and x[date] >= Date.AddMonths([date], -12))[dap]) else null, type number)

Any references to #"Changed Type" should be replaced with the previous step in your query.





Did I answer your question? Mark my post as a solution!

Proud to be a Super User!





Oh, wow--this is terrific.  Thank you!  I haven't completed testing it (my dataset is very large), but the first time I ran it, I realized that there were numbers greater than 12 (which shouldn't happen if it's only summing the 12 months prior to that date).  So, I added another part to the Table.SelectRows function so that it now reads,

 

= Table.AddColumn(#"Changed Type", "last12ddelq", each if [month] > 12 then List.Sum(Table.SelectRows(#"Changed Type", (x)=> x[loan_id]= [loan_id] and x[date] >= Date.AddMonths([date], -12) and x[date]< [date])[delinquency_b]) else null, type number)

 

I'll post again if/when it completes and hopefully works.  Thanks, @jgeddes!  (And duly noted on the new thread--thanks.)

wdx223_Daniel
Super User
Super User

= #table(Table.ColumnNames(PreviousStepName)&{"Removals L12M"},List.Accumulate(Table.ToRows(PreviousStepName),{{},{},""},(x,y)=>let a=List.Skip(x{1}&{y},each _{0}<Date.AddMonths(y{0},-12)) in if x{2}=y{1} then {x{0}&{y&{List.Sum(List.Zip(a){2})}},a,y{1}} else {x{0}&{y&{y{2}}},{y},y{1}}){0})

wdx223_Daniel_0-1668737556165.png

 

ppm1
Solution Sage
Solution Sage

Here's one way to do it in the query editor.  To see how it works, just create a blank query, open the Advanced Editor and replace the text there with the M code below.

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("Xc9LDsAgCATQu7A2cUBt7LK9hvH+1xA/qZbFhMVLBiiFcHuwFwiTo0fDI9UVYjEkmjAIYZEsSpo8KRnCpnjQO8q+wmyo74zzDBjCJjbU5/U/IxyF+ldt", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [#"Reference Date" = _t, Component = _t, #"Monthly Removals" = _t, #"Removals L12M" = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Reference Date", type date}, {"Component", type text}, {"Monthly Removals", Int64.Type}, {"Removals L12M", Int64.Type}}),
    #"Added Custom" = Table.AddColumn(#"Changed Type", "Custom", each let
thisdate = [Reference Date],
thiscomponent = [Component],
prev12mrows = Table.SelectRows(#"Changed Type", each ([Component] = thiscomponent and ([Reference Date] <= thisdate and [Reference Date] >= Date.AddMonths(thisdate, -12)))),
sum = List.Sum(prev12mrows[Monthly Removals])
in 
sum)
in
    #"Added Custom"

Pat

Microsoft Employee
JamesRobson
Resolver II
Resolver II

Hi,

 

 Not sure I fully follow the logic as your first line 09/01/21 isn't within the last 12 months but you have summed it?

Also does it need to have the sum at each line as per example or would a total applied to everyline suffice? i.e.

Reference DateComponentMonthly RemovalsRemovals L12M
09/01/2021A18
12/01/2021A28
03/01/2022A58
05/01/2022A08

 

if the latter is applicable you could add a helper column to group by Component and last 12 months, something like....

 

let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Reference Date", type date}, {"Component", type text}, {"Monthly Removals", Int64.Type}}),
#"Added DateCheck" = Table.AddColumn(#"Changed Type", "DateCheck", each if Date.IsInPreviousNMonths([#"Reference Date"], 12) then "Yes" else "No"),
#"Grouped Rows" = Table.Group(#"Added DateCheck", {"Component", "DateCheck"}, {{"Group", each List.Sum([Monthly Removals]), type nullable number}}),
#"Added Removals Sum" = Table.AddColumn(#"Grouped Rows", "Monthly Removals Sum", each if [DateCheck] = "No" then null else [Group], type number)
in
#"Added Removals Sum"

 

 

then merge back into orginal query.

 

Thanks,

Anonymous
Not applicable

Hi James,

 

I need to sum the L12M removals relative to the each reference date. For example, on the first line, L12M would be 10/01/2020 to 09/01/2021.

Helpful resources

Announcements
Las Vegas 2025

Join us at the Microsoft Fabric Community Conference

March 31 - April 2, 2025, in Las Vegas, Nevada. Use code MSCUST for a $150 discount!

FebPBI_Carousel

Power BI Monthly Update - February 2025

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

Feb2025 NL Carousel

Fabric Community Update - February 2025

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

Top Solution Authors