March 31 - April 2, 2025, in Las Vegas, Nevada. Use code MSCUST for a $150 discount! Early bird discount ends December 31.
Register NowBe one of the first to start using Fabric Databases. View on-demand sessions with database experts and the Microsoft product team to learn just how easy it is to get started. Watch now
Hi All!
Hope you guys can help me with this one.
I'm trying to figure out how many customers were won or lost on a specific month and then aggregate on higher levels.
The image above shows the 2 tables I'm using:
In order to evaluate if the customer was lost or won, I'm using the company's rule and created the following measures:
# Net Sales Actual Month
# Year-to-Date Net Sales (Sum from January till Actual Month)
I believe the problem starts here:
Solved! Go to Solution.
[Win/Loss Ratio] =
var Wins =
COUNTROWS(
FILTER(
// CustomerID must uniquely identify
// a customer.
DISTINCT( Customer[CustomerID] ),
[Win or Loss] = "Win"
)
)
var Losses =
COUNTROWS(
FILTER(
// CustomerID must uniquely identify
// a customer.
DISTINCT( Customer[CustomerID] ),
[Win or Loss] = "Loss"
)
)
var Result =
DIVIDE( Wins, Losses )
return
Result
By the way, Customer must be its own dimension. If you keep a design as the one above, don't be surprised when the figures will randomly get distorted and you won't be able to find out where they come from. One-table models like the one above have a potential (very real) to give you wrong numbers even for good formulas. Beware of one-table models!
If you want to see what I'm talking about, you can watch this: (1) Auto-exist on clusters or numbers - Unplugged #22 - YouTube
Here's another way (might be faster) to write your measure:
[Win/Loss Ratio] =
var WinLossTable =
FILTER(
ADDCOLUMNS(
DISTINCT( Customer[CustomerID] ),
"@WinOrLoss",
[Win or Loss]
),
NOT ISBLANK( [@WinOrLoss] )
)
var Wins =
COUNTROWS(
FILTER(
WinLossTable,
[@WinOrLoss] = "Win"
)
)
var Losses =
COUNTROWS(
FILTER(
WinLossTable,
[@WinOrLoss] = "Loss"
)
)
var Result =
DIVIDE( Wins, Losses )
return
Result
And still another (could be even faster than the one above):
[Win/Loss Ratio] =
var WinLossTable =
FILTER(
ADDCOLUMNS(
DISTINCT( Customer[CustomerID] ),
"@WinOrLoss",
[Win or Loss]
),
NOT ISBLANK( [@WinOrLoss] )
)
var Wins =
COUNTROWS(
FILTER(
WinLossTable,
[@WinOrLoss] = "Win"
)
)
var TotalCusts =
COUNTROWS( WinLossTable )
var Result =
DIVIDE( Wins, TotalCusts - Wins )
return
Result
"What I'm trying to accomplish now is to SUM the [Net Sales] and measure how much I won, but only for the customers that are still a "win" in the month I selected on the Slicer, if I lost them again during the year, I should not consider their [Net Sales]."
// With a proper model (where Dates is a date dimension table),
// you would write:
[Total Net Sales] = SUM( FactTable[Net Sales] )
[Total Net Sales (Wins+)] =
var WinCustomersInCurrentPeriod =
FILTER(
DISTINCT( Customer[CustomerID] ),
[Win or Loss] = "Win"
)
var PeriodAfterCurrentPeriodWithinSameYear =
var LastVisibleDate = MAX( Dates[Date] )
// Dates[Year] must be an int. If it's not,
// then use a column that is an int and
// encodes years.
var LastVisibleYear = MAX( Dates[Year] )
return
CALCULATETABLE(
DISTINCT( Dates[Date] ),
LastVisibleDate < Dates[Date],
Dates[Date] <= DATE(LastVisibleYear, 12, 31),
// REMOVEFILTERS is not necessary if
// Dates is marked as a date table
// in the model. Otherwise, you should
// use it.
REMOVEFILTERS( Dates )
)
var CustomersNotLostAfterCurrentPeriodWithinSameYear =
FILTER(
DISTINCT( Customer[CustomerID] ),
CALCULATE(
[Win or Loss] <> "Loss",
PeriodAfterCurrentPeriodWithinSameYear,
REMOVEFILTERS( Dates )
)
)
var CustomersInIntersection =
INTERSECT(
WinCustomersInCurrentPeriod,
CustomersNotLostAfterCurrentPeriodWithinSameYear
)
var TotalNetSalesForIntersection =
CALCULATE(
[Total Net Sales],
CustomersInIntersection
)
return
TotalNetSalesForIntersection
By the way, your YTD measures are not quite correct 🙂 They will, as much as I can tell, return figures even for periods in the calendar that are in the future. Also, comparing YTD to prior YTD will be incorrect for periods that cover TODAY. If a period contains TODAY, the context must be adjusted so that like for like periods are compared.
[Win/Loss Ratio] =
var Wins =
COUNTROWS(
FILTER(
// CustomerID must uniquely identify
// a customer.
DISTINCT( Customer[CustomerID] ),
[Win or Loss] = "Win"
)
)
var Losses =
COUNTROWS(
FILTER(
// CustomerID must uniquely identify
// a customer.
DISTINCT( Customer[CustomerID] ),
[Win or Loss] = "Loss"
)
)
var Result =
DIVIDE( Wins, Losses )
return
Result
By the way, Customer must be its own dimension. If you keep a design as the one above, don't be surprised when the figures will randomly get distorted and you won't be able to find out where they come from. One-table models like the one above have a potential (very real) to give you wrong numbers even for good formulas. Beware of one-table models!
If you want to see what I'm talking about, you can watch this: (1) Auto-exist on clusters or numbers - Unplugged #22 - YouTube
Here's another way (might be faster) to write your measure:
[Win/Loss Ratio] =
var WinLossTable =
FILTER(
ADDCOLUMNS(
DISTINCT( Customer[CustomerID] ),
"@WinOrLoss",
[Win or Loss]
),
NOT ISBLANK( [@WinOrLoss] )
)
var Wins =
COUNTROWS(
FILTER(
WinLossTable,
[@WinOrLoss] = "Win"
)
)
var Losses =
COUNTROWS(
FILTER(
WinLossTable,
[@WinOrLoss] = "Loss"
)
)
var Result =
DIVIDE( Wins, Losses )
return
Result
And still another (could be even faster than the one above):
[Win/Loss Ratio] =
var WinLossTable =
FILTER(
ADDCOLUMNS(
DISTINCT( Customer[CustomerID] ),
"@WinOrLoss",
[Win or Loss]
),
NOT ISBLANK( [@WinOrLoss] )
)
var Wins =
COUNTROWS(
FILTER(
WinLossTable,
[@WinOrLoss] = "Win"
)
)
var TotalCusts =
COUNTROWS( WinLossTable )
var Result =
DIVIDE( Wins, TotalCusts - Wins )
return
Result
Thank you @daxer-almighty ! You are the best! You saved my life! 🙂
I was wondering if you could give just one more help 🙂
I worked on the tips you gave me, and now I have the FACT table separated (as you can see below). Those tables come straight from the company's Analysis Services.
With your help, I was able to count how many wins I have for each month, I'm using the first formula you gave me, using the "Performance Analyzer" seems to be the fastest one. What I'm trying to accomplish now is to SUM the [Net Sales] and measure how much I won, but only for the customers that are still a "win" in the month I selected on the Slicer, if I lost them again during the year, I should not consider their [Net Sales].
I have a Slicer, as shown above, the users can select the "Year" and "Month" they want to analyze. The issue is, I want to SUM only when there is a Win on the month I selected. So, if I won a client in January and lost him in May, it should not count and SUM the [Net Sales] for that Customer. On the other hand, if I won a client in April and it is still a win in June (The month I selected), I want to SUM its revenue.
I want to SUM the [Net Sales] only when [Wins] = 1 (Using the formulas you gave me) and [Date] = DateSelected (From Slicer). This formula is SUMMING the Net Revenues even if I've already lost the customer. I basically want to sum if [Wins] = 1 on the month selected.
March 31 - April 2, 2025, in Las Vegas, Nevada. Use code MSCUST for a $150 discount!
Arun Ulag shares exciting details about the Microsoft Fabric Conference 2025, which will be held in Las Vegas, NV.
User | Count |
---|---|
22 | |
19 | |
17 | |
9 | |
5 |
User | Count |
---|---|
37 | |
29 | |
16 | |
14 | |
12 |