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

Join the Fabric FabCon Global Hackathon—running virtually through Nov 3. Open to all skill levels. $10,000 in prizes! Register now.

Reply
samdep
Advocate II
Advocate II

Consecutive Count by CustomerId, SubscriptionId & Status

Hi PBI Community!

 

I have a table of data similar to the below - and am looking to get a count of consecutive closed-lost opportunities by CustomerId and SubscriptionId.

 

I've seen a couple of consecutive count tutorials, but none that also factor in an additional layer of 'by customer' and 'by subscription' as well since a customer can have more than one subscription at a given time.

 

Basically, once a customer has four consecutive months of a closed-lost subscription, their overall subscription moves to cancelled -- so, I'm trying to flag those that might be on the cusp of an overall cancellation.

 

CustomerIdSubscriptionIdCloseDateAmountStage
CustomerA1A3/1/2021$10Closed-Lost
CustomerA1A2/1/2021$10Closed-Lost
CustomerB2A1/1/2021$5Closed-Won
CustomerA1A1/1/2021$5Closed-Won

 

As of 1/1, Cust A has 0 Closed-Lost opps, but as of 3/1, Cust A now has 2 consecutive closed-lost opps. Unsure if a conditional column or measure makes more sense here, but any ideas are greatly appreciated.

 

Many Thanks!

1 ACCEPTED SOLUTION

Hi @samdep 

I have a solution for this scenario, 

(1) Create a column in Power Query,

M code:

 

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMjQyVtJRcgRi55z84tQUBZ/84hIgT8XIAEga6xvpGxkYGQGZJkqxOtFK5haW2JWbQpQbwpQbKoDV4zfeCGE8EaoNSVMNNdwQp/Lw/DyEakOSVBuQotoSTbGJqRmQ6YTpbkNoGMK9aUyEeiMk9UQoNySoHOp0Q2ggIiuPBQA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [DonorId = _t, SubscriptionId = _t, StageName = _t, OpportunityAmount = _t, CloseDate = _t, #"Goal Column or Measure" = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"DonorId", type text}, {"SubscriptionId", type text}, {"StageName", type text}, {"OpportunityAmount", Currency.Type}, {"CloseDate", type date}, {"Goal Column or Measure", type text}}),
    #"Sorted Rows" = Table.Sort(#"Changed Type",{{"CloseDate", Order.Ascending}}),
    #"Add Column"= Table.AddColumn(#"Sorted Rows", "Count",  (r) => if r[StageName] = "Closed Lost"
           then List.Count(
                    List.LastN(
                        Table.SelectRows(
                            #"Sorted Rows",
                            each [DonorId] = r[DonorId] and [SubscriptionId]=r[SubscriptionId] and [CloseDate] <= r[CloseDate]
                        )[StageName],
                        each _ = "Closed Lost"
                    )
                )
           else 0)
in
    #"Add Column"

 

then it returns a column

vxiaotang_0-1647511551499.png

(2) then create a calculated column with DAX code

 

Column = 
var _closedate= CALCULATE(MAX('test'[CloseDate]),FILTER('test','test'[DonorId]=EARLIER('test'[DonorId]) && test[SubscriptionId]=EARLIER( test[SubscriptionId]) && test[Count]>0))
return IF(test[CloseDate]= _closedate,test[Count],BLANK())

 

vxiaotang_1-1647511600630.png

 

Best Regards,

Community Support Team _Tang

If this post helps, please consider Accept it as the solution to help the other members find it more quickly.

View solution in original post

3 REPLIES 3
samdep
Advocate II
Advocate II

Hi @littlemojopuppy - thanks for your response! I don't think I have the ability to attach a pbix file, but I sent it to myself as a wetransfer link https://wetransfer.com/downloads/57c7819c26fae486a3639749e843940020220312215902/ea00416c805bf49cb9c7...

 

Hopefully, you can access this sample data. I was thinking that if I could create a conditional column or measure that places the count of consecutive closed-lost opportunities on the max date record by donor, that would solve for my need - ie: doesn't need to be a running count on every record, just the latest or max date by donor. Thanks again for looking into this!

Hi @samdep 

I have a solution for this scenario, 

(1) Create a column in Power Query,

M code:

 

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMjQyVtJRcgRi55z84tQUBZ/84hIgT8XIAEga6xvpGxkYGQGZJkqxOtFK5haW2JWbQpQbwpQbKoDV4zfeCGE8EaoNSVMNNdwQp/Lw/DyEakOSVBuQotoSTbGJqRmQ6YTpbkNoGMK9aUyEeiMk9UQoNySoHOp0Q2ggIiuPBQA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [DonorId = _t, SubscriptionId = _t, StageName = _t, OpportunityAmount = _t, CloseDate = _t, #"Goal Column or Measure" = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"DonorId", type text}, {"SubscriptionId", type text}, {"StageName", type text}, {"OpportunityAmount", Currency.Type}, {"CloseDate", type date}, {"Goal Column or Measure", type text}}),
    #"Sorted Rows" = Table.Sort(#"Changed Type",{{"CloseDate", Order.Ascending}}),
    #"Add Column"= Table.AddColumn(#"Sorted Rows", "Count",  (r) => if r[StageName] = "Closed Lost"
           then List.Count(
                    List.LastN(
                        Table.SelectRows(
                            #"Sorted Rows",
                            each [DonorId] = r[DonorId] and [SubscriptionId]=r[SubscriptionId] and [CloseDate] <= r[CloseDate]
                        )[StageName],
                        each _ = "Closed Lost"
                    )
                )
           else 0)
in
    #"Add Column"

 

then it returns a column

vxiaotang_0-1647511551499.png

(2) then create a calculated column with DAX code

 

Column = 
var _closedate= CALCULATE(MAX('test'[CloseDate]),FILTER('test','test'[DonorId]=EARLIER('test'[DonorId]) && test[SubscriptionId]=EARLIER( test[SubscriptionId]) && test[Count]>0))
return IF(test[CloseDate]= _closedate,test[Count],BLANK())

 

vxiaotang_1-1647511600630.png

 

Best Regards,

Community Support Team _Tang

If this post helps, please consider Accept it as the solution to help the other members find it more quickly.

littlemojopuppy
Community Champion
Community Champion

@samdep can you share some raw data to work with?

Helpful resources

Announcements
FabCon Global Hackathon Carousel

FabCon Global Hackathon

Join the Fabric FabCon Global Hackathon—running virtually through Nov 3. Open to all skill levels. $10,000 in prizes!

September Power BI Update Carousel

Power BI Monthly Update - September 2025

Check out the September 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.