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 August 31st. Request your voucher.

Reply
lemoncheesecake
New Member

Count the number of trailing consecutive months based on multiple criteria

Hi,

 

I am working on a dashboard where I have to count the number of the latest consecutive months by region that meet mulitple criteria, which in this case is 1) the monthly sales is lower than the average monthly sales for the region, and 2) the monthly sales is less than or equal to 20. There is also a peculiarity in the data where when there is no sales data, there is a gap in time like in this example for Croydon between February and May. I was thinking of addressing this gap by adding a column which is the number of months between the previous row and the current row if they share the same region, and my measure would be a SUMIFS.

 

The consecutive trailing months would be for instance in Bexley, February 2025 is beneath the criteria threshold, but is not consecutive with the latest month in the data because March 2025 is above the threshold, thus it would only count April 2025 to June 2025 (three months).

 

However, I do not know how write in DAX any formula that can count the latest consecutive months based on multiple criteria. The expected output for the below snippet of data would be like the second table. Could anyone please offer a hand on creating a functional formula?

 

Thank you very much in advance! 

 

RegionMonth Sales (GBP)Average Monthly Sales (GBP)Variance in Months
Bromley1/11/2024 2418.331
Bromley1/12/2024 3018.331
Bromley1/01/2025 1318.331
Bromley1/02/2025 1318.331
Bromley1/03/2025 1718.331
Bromley1/04/2025 1318.331
Bexley1/09/2024 1130.501
Bexley1/10/2024 2430.501
Bexley1/11/2024 6230.501
Bexley1/12/2024 6330.501
Bexley1/01/2025 5430.501
Bexley1/02/2025 1630.501
Bexley1/03/2025 3530.501
Bexley1/04/2025 1230.501
Bexley1/05/2025 1330.501
Bexley1/06/2025 1530.501
Croydon1/09/2024 2018.751
Croydon1/10/2024 1518.751
Croydon1/11/2024 3518.751
Croydon1/12/2024 2418.751
Croydon1/01/2025 2318.751
Croydon1/02/2025 918.751
Croydon1/05/2025 1018.753
Croydon1/06/2025 1418.751

 

lemoncheesecake_1-1752670760151.png

 

 

1 ACCEPTED SOLUTION

Hi @lemoncheesecake ,

what I can do is post the DAX here and let anyone that wants an explanation to ask it and I shall answer. Point is that it is a very complex DAX

 

I hope you can mark it as a solution anyway.

 

here is the DAX of the measure

 

MaxConsMonths =
VAR MinumumMonth = CALCULATE( MIN ( Sales[YearMonthNr] ), REMOVEFILTERS( 'Date' ) )
VAR MaximumMonth = CALCULATE( MAX ( Sales[YearMonthNr] ), REMOVEFILTERS( 'Date' ) )
VAR Months =
SELECTCOLUMNS(
FILTER (
    ADDCOLUMNS(
    ADDCOLUMNS(
        CROSSJOIN( ALL ( 'Date'[YearMonthNr], 'Date'[YearMonth] ), VALUES ( Region[Region] ) ),
        "@Sales", CALCULATE( SUM ( Sales[Sales (GBP)] ) )
       
    ),
     "@ToCons", IF ( [@Sales] > 0, CALCULATE( SELECTEDVALUE( Sales[To Consider] , 0 ) ), 1 )
    ),
    [@ToCons] = 1 &&
    'Date'[YearMonthNr] >=MinumumMonth && 'Date'[YearMonthNr] <=MaximumMonth
),
'Date'[YearMonth], 'Date'[YearMonthNr], Region[Region]
)
VAR ConsecutiveMonths =
ADDCOLUMNS(
    Months,
    "@ConsecMonth",
    VAR Region = Region[Region]
    VAR RefMonth = [YearMonthNr]
    VAR PrevMonth =
    MAXX ( FILTER ( Months, [YearMonthNr] < RefMonth ), [YearMonthNr] )
    VAR _NextMonth =
    MINX ( FILTER ( Months, [YearMonthNr] > RefMonth ), [YearMonthNr] )
    VAR Result = IF ( PrevMonth = RefMonth-1 || _NextMonth = RefMonth+1, 1, 0  )
    RETURN
    Result,
    "@ConsFromCalendar",
    VAR Region = Region[Region]
    VAR RefMonth = [YearMonthNr]
    VAR PrevMonth =
    MAXX ( FILTER ( Months, [YearMonthNr] < RefMonth ), [YearMonthNr] )
    VAR PrevMonthCal =
    MAXX ( FILTER ( ALL ( 'Date'[YearMonthNr] ), [YearMonthNr] < RefMonth ), [YearMonthNr] )
    VAR _NextMonth =
    MINX ( FILTER ( Months, [YearMonthNr] > RefMonth ), [YearMonthNr] )
    VAR _NextMonthCal =
    MINX ( FILTER ( ALL ( 'Date'[YearMonthNr] ), [YearMonthNr] > RefMonth ), [YearMonthNr] )
    VAR Result = IF ( PrevMonth = PrevMonthCal, 1, 0  )
    RETURN
    Result
)
VAR NumberConsecutiveMonths =
ADDCOLUMNS(
    ConsecutiveMonths,
    "@NrConsMonths",
    VAR RefMonth = [YearMonthNr]
    VAR First = MAXX ( FILTER ( ConsecutiveMonths, [YearMonthNr]<=RefMonth && [@ConsecMonth] = 1 && [@ConsFromCalendar] = 0 ), [YearMonthNr])
    RETURN IF ( [@ConsecMonth] = 1, RefMonth-First+1 )
)
VAR MaxMOnthNonConsCal = MAXX ( FILTER ( NumberConsecutiveMonths, [@ConsFromCalendar] = 0 ), 'Date'[YearMonthNr] )
VAR MaxNrConsMonths = MAXX( FILTER ( NumberConsecutiveMonths, 'Date'[YearMonthNr]>=MaxMOnthNonConsCal), [@NrConsMonths] )
VAR MonthsIncludedInMaxNrConsMonths =
SELECTCOLUMNS(
    FILTER ( NumberConsecutiveMonths, [@NrConsMonths] = MaxNrConsMonths ),
    'Date'[YearMonthNr]
)
RETURN IF ( MaximumMonth IN MonthsIncludedInMaxNrConsMonths, MaxNrConsMonths)
 

If this helped, please consider giving kudos and mark as a solution

@me in replies or I'll lose your thread

consider voting this Power BI idea

Francesco Bergamaschi

MBA, M.Eng, M.Econ, Professor of BI

View solution in original post

31 REPLIES 31

The file I uploaded has the updated data set. 

lemoncheesecake_0-1753278269043.png

 

unfortunately I do not see those numbers, I am not sure why

 

Let's do like this: I send you my mail via private message and you send me the pbix there ok? A private message is coming

Now I have this result

 

FBergamaschi_0-1753282391189.png

 

is that ok? 

 

File is again at my googledrive

https://drive.google.com/drive/folders/1KIQxJSgsL3m7YKd3-qf3JyVFpUKoAjPX?usp=sharing

 

If this helped, please consider giving kudos and mark as a solution

@me in replies or I'll lose your thread

consider voting this Power BI idea

Francesco Bergamaschi

MBA, M.Eng, M.Econ, Professor of BI

 

@FBergamaschi  Yes, that's perfect. I get the same result and I did a larger spot check with my population data, and they match what I would get with manual calculation.

 

Thank you for your help!

 

If you are going to post again with an explanation of your solution for everyone else, then I'll mark that as the solution.

 

Thanks again.

Hi @lemoncheesecake ,

what I can do is post the DAX here and let anyone that wants an explanation to ask it and I shall answer. Point is that it is a very complex DAX

 

I hope you can mark it as a solution anyway.

 

here is the DAX of the measure

 

MaxConsMonths =
VAR MinumumMonth = CALCULATE( MIN ( Sales[YearMonthNr] ), REMOVEFILTERS( 'Date' ) )
VAR MaximumMonth = CALCULATE( MAX ( Sales[YearMonthNr] ), REMOVEFILTERS( 'Date' ) )
VAR Months =
SELECTCOLUMNS(
FILTER (
    ADDCOLUMNS(
    ADDCOLUMNS(
        CROSSJOIN( ALL ( 'Date'[YearMonthNr], 'Date'[YearMonth] ), VALUES ( Region[Region] ) ),
        "@Sales", CALCULATE( SUM ( Sales[Sales (GBP)] ) )
       
    ),
     "@ToCons", IF ( [@Sales] > 0, CALCULATE( SELECTEDVALUE( Sales[To Consider] , 0 ) ), 1 )
    ),
    [@ToCons] = 1 &&
    'Date'[YearMonthNr] >=MinumumMonth && 'Date'[YearMonthNr] <=MaximumMonth
),
'Date'[YearMonth], 'Date'[YearMonthNr], Region[Region]
)
VAR ConsecutiveMonths =
ADDCOLUMNS(
    Months,
    "@ConsecMonth",
    VAR Region = Region[Region]
    VAR RefMonth = [YearMonthNr]
    VAR PrevMonth =
    MAXX ( FILTER ( Months, [YearMonthNr] < RefMonth ), [YearMonthNr] )
    VAR _NextMonth =
    MINX ( FILTER ( Months, [YearMonthNr] > RefMonth ), [YearMonthNr] )
    VAR Result = IF ( PrevMonth = RefMonth-1 || _NextMonth = RefMonth+1, 1, 0  )
    RETURN
    Result,
    "@ConsFromCalendar",
    VAR Region = Region[Region]
    VAR RefMonth = [YearMonthNr]
    VAR PrevMonth =
    MAXX ( FILTER ( Months, [YearMonthNr] < RefMonth ), [YearMonthNr] )
    VAR PrevMonthCal =
    MAXX ( FILTER ( ALL ( 'Date'[YearMonthNr] ), [YearMonthNr] < RefMonth ), [YearMonthNr] )
    VAR _NextMonth =
    MINX ( FILTER ( Months, [YearMonthNr] > RefMonth ), [YearMonthNr] )
    VAR _NextMonthCal =
    MINX ( FILTER ( ALL ( 'Date'[YearMonthNr] ), [YearMonthNr] > RefMonth ), [YearMonthNr] )
    VAR Result = IF ( PrevMonth = PrevMonthCal, 1, 0  )
    RETURN
    Result
)
VAR NumberConsecutiveMonths =
ADDCOLUMNS(
    ConsecutiveMonths,
    "@NrConsMonths",
    VAR RefMonth = [YearMonthNr]
    VAR First = MAXX ( FILTER ( ConsecutiveMonths, [YearMonthNr]<=RefMonth && [@ConsecMonth] = 1 && [@ConsFromCalendar] = 0 ), [YearMonthNr])
    RETURN IF ( [@ConsecMonth] = 1, RefMonth-First+1 )
)
VAR MaxMOnthNonConsCal = MAXX ( FILTER ( NumberConsecutiveMonths, [@ConsFromCalendar] = 0 ), 'Date'[YearMonthNr] )
VAR MaxNrConsMonths = MAXX( FILTER ( NumberConsecutiveMonths, 'Date'[YearMonthNr]>=MaxMOnthNonConsCal), [@NrConsMonths] )
VAR MonthsIncludedInMaxNrConsMonths =
SELECTCOLUMNS(
    FILTER ( NumberConsecutiveMonths, [@NrConsMonths] = MaxNrConsMonths ),
    'Date'[YearMonthNr]
)
RETURN IF ( MaximumMonth IN MonthsIncludedInMaxNrConsMonths, MaxNrConsMonths)
 

If this helped, please consider giving kudos and mark as a solution

@me in replies or I'll lose your thread

consider voting this Power BI idea

Francesco Bergamaschi

MBA, M.Eng, M.Econ, Professor of BI

Hi @FBergamaschi ,

 

Thanks for confirming!

Since you asked for a more specific implementation, here’s a starting DAX formula to identify qualified months:

 

IsQualifiedMonth =
VAR RegionAvg = CALCULATE(AVERAGE('Sales'[MonthlySales]), ALLEXCEPT('Sales', 'Sales'[Region]))
RETURN IF('Sales'[MonthlySales] <= 20 && 'Sales'[MonthlySales] < RegionAvg, 1, 0)

 

Then in Power Query, sort your table by Region and Month, and create an Index column (starting at 1 per Region). Use DAX with EDATE logic to group streaks where qualified months are consecutive. Finally, summarize to get the max streak per Region.

 

Thank you again.

 

 

Hi @lemoncheesecake ,

Thanks for reaching out to the Microsoft fabric community forum.

 

Here's a clear approach to identifying the latest consecutive months for each region where monthly sales are (1) less than or equal to 20, and (2) also below the region’s average, ensuring no missing months in between. This can be achieved entirely in Power BI using DAX, without inserting dummy rows.

Start by adding a calculated column, IsQualifiedMonth, which returns 1 if a month’s sales are less than or equal to 20 and below the region’s average (use a VAR to store the average for comparison). In Power Query, add an Index column that starts from 1 per region, sorted by month.

 

Next, create a DAX column to group consecutive qualifying months by checking if the current month is one month after the previous (using EDATE) and both are qualified. This allows you to assign a group ID to each streak.

Summarize by region and group ID to count the months in each streak, then create another summary table to find the maximum streak length for each region. The result will give you the longest run of consecutive qualifying months per region, matching the example output such as 3 for Bexley, 4 for Bromley, and 5 for Croydon.

 

If you need the specific DAX formulas or a sample PBIX file, let me know.

 

Thank you,

Tejaswi.

@v-tejrama Hi Tejaswi,

 

I would greatly appreciate a sample PBIX file or the specific formulae for this solution. I am not fully familiar with storing VAR. One thing I noticed about both your solution and @FBergamaschi's solution is that it calculates the maximum streak, but my problem requires the size of the latest streak at the end of the available data for each region. For example, if we had a fourth region, Leiceister with the following data set (below), the solution would show 0 for this region, because while there are months below the threshold, the latest streak is above the threshold.

 

Region Month SalesAverage
Leiceister 1/11/2024 1521.63
Leiceister 1/12/2024 1221.63
Leiceister 1/01/2025 1621.63
Leiceister 1/02/2025 2921.63
Leiceister 1/03/2025 2021.63
Leiceister 1/04/2025 2321.63
Leiceister 1/05/2025 3221.63
Leiceister 1/06/2025 2621.63

Hi again @lemoncheesecake ,

Thanks for the follow up,

You can easily achieve this in Power BI. Start by loading your data with the columns: Region, Month (as Date), Sales, and Average.

 

Next, create a calculated column:

 

IsQualifiedMonth = IF(Sales[Sales] <= 20 && Sales[Sales] < Sales[Average], 1, 0)

 

In Power Query, sort your data by Region and Month in ascending order, then add an index column for each Region (such as IndexInRegion). Once you apply these changes, define a DAX measure to determine the latest qualified streak—check if the most recent month qualifies, and count how many consecutive months (going backwards) also qualify. Add both Region and this measure to a table visual. This approach will deliver the latest streak for each Region, not the maximum streak, giving you exactly the insight you need.

Please find the attached PBIX and Screenshort file for your reference.

 

vtejrama_1-1753265569685.png

 

Best Regards,
Tejaswi.

Greg_Deckler
Community Champion
Community Champion

@lemoncheesecake It would be some variation of Cthulhu. Cthulhu - Microsoft Fabric Community The latest iteration of Cthulhu is in my newest book (below). If I get a chance I will try to adapt it to your criteria. That said, I'm not sure I understand the criteria fully. It looks like Bexley is always above 20 so it shouldn't have any and be zero?



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...

Sorry, it looks the formatting of the data I copied over doesn't look too great. The Sales looks like it's concatenated with the date. For Bexley, in June 2025, the monthly sales is 15, which is lower than the threshold of the average and the 20 absolute days.

Helpful resources

Announcements
July 2025 community update carousel

Fabric Community Update - July 2025

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

July PBI25 Carousel

Power BI Monthly Update - July 2025

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

Join our Fabric User Panel

Join our Fabric User Panel

This is your chance to engage directly with the engineering team behind Fabric and Power BI. Share your experiences and shape the future.