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

Enhance your career with this limited time 50% discount on Fabric and Power BI exams. Ends September 15. Request your voucher.

Reply
VO
Helper I
Helper I

Rolling Average Last 20 Working Days (Exclude Non Working Days)

Fact table, Job. Calendar table, Calendar. Would like to get the 20 working day rolling average (days with zero, no activity, included as long as it is a working day),  when it gets to 20 working days or more transactions.

For less than 20 working days (initial range at the beginning before 20 working days), average the cumulative working days.

Non Working Days, Column 'Calendar'[IsWorkingDay], include: Sundays, Public Holidays & other special days (depending on circumstances).

Case in point (from tables below),

>10-Mar-2020: Rolling 20 day Average= 57.5 [8 working days]
>30-Mar-2020: Rolling 20 day Average= 80.85 [20 working days] (inclusive 23-Mar-2020 & 24-Mar-2020, no amount/activity despite it being a working day)
>31-Mar-2020: Rolling 20 day Average= 79.85 [20 working days] (inclusive 23-Mar-2020 & 24-Mar-2020, no amount/activity despite it being a working day)

 

Table Name: Job

DatePaid
02-Mar-2020
03-Mar-2030
04-Mar-2040
05-Mar-2050
06-Mar-2060
07-Mar-2070
09-Mar-2090
10-Mar-20100
11-Mar-20110
12-Mar-20120
16-Mar-20102
17-Mar-2062
18-Mar-20101
19-Mar-2094
20-Mar-20136
21-Mar-20119
25-Mar-20125
26-Mar-2043
27-Mar-20144
28-Mar-2039
30-Mar-2052

 

Table Name: Calendar

DateDayOfWeekIsWorkingDayWeekDayNumberIsWorkingIndicator
01-Mar-20SundayNon Working10
02-Mar-20MondayWorking21
03-Mar-20TuesdayWorking31
04-Mar-20WednesdayWorking41
05-Mar-20ThursdayWorking51
06-Mar-20FridayWorking61
07-Mar-20SaturdayWorking71
08-Mar-20SundayNon Working10
09-Mar-20MondayWorking21
10-Mar-20TuesdayWorking31
11-Mar-20WednesdayWorking41
12-Mar-20ThursdayWorking51
13-Mar-20FridayNon Working60
14-Mar-20SaturdayNon Working70
15-Mar-20SundayNon Working10
16-Mar-20MondayWorking21
17-Mar-20TuesdayWorking31
18-Mar-20WednesdayWorking41
19-Mar-20ThursdayWorking51
20-Mar-20FridayWorking61
21-Mar-20SaturdayWorking71
22-Mar-20SundayNon Working10
23-Mar-20MondayWorking21
24-Mar-20TuesdayWorking31
25-Mar-20WednesdayWorking41
26-Mar-20ThursdayWorking51
27-Mar-20FridayWorking61
28-Mar-20SaturdayWorking71
29-Mar-20SundayNon Working10
30-Mar-20MondayWorking21
31-Mar-20TuesdayWorking31
1 ACCEPTED SOLUTION
Anonymous
Not applicable

Here's the clean code:

 

// 20 [W]orking [D]ay Rolling Avg
[20WD Rolling Avg] =
var __workingDays = 20
var __currentDay = MAX( 'Calendar'[Date] )
var __daysToAvgOver =
	TOPN(__workingDays,
		CALCULATETABLE(
			'Calendar',
			'Calendar'[Date] <= __currentDay,
			'Calendar'[IsWorkingIndicator] = 1,
			ALL( 'Calendar' )
		),
		'Calendar'[Date],
		DESC
	)
var __avg =
	DIVIDE(
		CALCULATE(
			SUM( Job[Paid] ),
			__daysToAvgOver
		),
		COUNTROWS( __daysToAvgOver )
	)
return
	__avg

 

Best

D

View solution in original post

5 REPLIES 5
Greg_Deckler
Community Champion
Community Champion

Perhaps something like:

 

 

Measure =
  VAR __Date = MAX('Table'[Date])
  VAR __Table = 
    ADDCOLUMNS(
      FILTER(
        ALL('Table'),
        [Date] <= __Date && [IsWorkingIndicator] = 1
      ),
      "__WorkDays",COUNTROWS(FILTER('Table','Table'[Date] <= EARLIER([Date]))
    )
  VAR __Max = MAXX(__Table,[__WorkDays])
  VAR __Lookup = IF(__Max >= 20,20,__Max)
RETURN
  AVERAGEX(FILTER(__Table,[__WorkDays] <= __Max),[Paid])

 

 

WARNING: I did not test this code.



Follow on LinkedIn
@ me in replies or I'll lose your thread!!!
Instead of a Kudo, please vote for this idea
Become an expert!: Enterprise DNA
External Tools: MSHGQM
YouTube Channel!: Microsoft Hates Greg
Latest book!:
DAX For Humans

DAX is easy, CALCULATE makes DAX hard...

Given there are 2 tables, Calendar & Job

'Table' refers to

Can't get it to work. Error: a single value for column Date in the table Job cannot be determined

Rolling Avg 20 Working Days :=
VAR __Date =
    MAX ( Job[Date] )
VAR __Table =
    ADDCOLUMNS (
        FILTER (
            ALL ( 'Calendar' ),
            Job[Date] <= __Date
                && 'Calendar'[IsWorkingIndicator] = 1
        ),
        "__WorkDays", COUNTROWS ( FILTER ( 'Calendar', 'Calendar'[Date] <= EARLIER ( Job[Date] ) ) )
    )
VAR __Max =
    MAXX ( __Table, [__WorkDays] )
VAR __Lookup =
    IF ( __Max >= 20, 20, __Max )
RETURN
    AVERAGEX ( FILTER ( __Table, [__WorkDays] <= __Max ), Job[Paid] )

 

Anonymous
Not applicable

Here's the clean code:

 

// 20 [W]orking [D]ay Rolling Avg
[20WD Rolling Avg] =
var __workingDays = 20
var __currentDay = MAX( 'Calendar'[Date] )
var __daysToAvgOver =
	TOPN(__workingDays,
		CALCULATETABLE(
			'Calendar',
			'Calendar'[Date] <= __currentDay,
			'Calendar'[IsWorkingIndicator] = 1,
			ALL( 'Calendar' )
		),
		'Calendar'[Date],
		DESC
	)
var __avg =
	DIVIDE(
		CALCULATE(
			SUM( Job[Paid] ),
			__daysToAvgOver
		),
		COUNTROWS( __daysToAvgOver )
	)
return
	__avg

 

Best

D

@Anonymous  thank you. It has yielded the expected results. Highly appreciated.

Helpful resources

Announcements
August Power BI Update Carousel

Power BI Monthly Update - August 2025

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

August 2025 community update carousel

Fabric Community Update - August 2025

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