I work for a subscription service and am looking to build a metric that shows weighted average revenue per unique customer over a time period (month, qtr and year). So basically if I only had one customer, and they paid $100 per month all year, then my chart would show $100 each month when drilled to month. When drilled up to quarter it'd say $300 each quarter, and year it'd say $1200.
Here is how my data looks on the Transaction Table. Note that it's a monthly subscription so an ID only shows up once per month.
I started with this Measure:
Avg Rev Per Customer1 =
DIVIDE ( SUM ( Transactions[Revenue] ), COUNTROWS ( Transactions ), 0 )
Which works fine when showing the data by month, but breaks when showing by quarter because a unique customer would show up 3 times on the denominator. Essentially this only gives me a monthly average, not dynamic. Which lead me to this measure:
Avg Rev Per Customer2 =
DIVIDE ( SUM ( Transactions[Revenue] ), DISTINCTCOUNT ( Transactions[ID] ), 0 )
This again works when drilled to month, but drilled to quarter and year it doesn't adequately weight for customers that weren't around for the full period. Example 35007 was around all of Q2, but 35002 was only around April and May. DISTINCTCOUNT puts them both as equals (1) on the denominator, where 35002 should be 66% of 35007. This is compounded even more at a year level.
So then I built this:
Avg Rev Per Customer3 - Qtr Only =
SUM ( Transactions[Revenue] ),
DIVIDE ( COUNTROWS ( Transactions ), 3, 0 ),
Which works only for quarters. I can build another for years (replace 3 with 12), but now I have 3 measures which don't drill down, and makes my charts all clunky and gross.
I need help thinking of a better way to measure this while still being able to use drill down.
Thanks in advance.
I create a table like below. I replaced all your revenue to 100 for being easy to see result in chart.
In this scenario, your calculation need to be evaluated on row level. Please using SUMX() instead of SUM().
avg revenue = CALCULATE(DIVIDE(sumx('Transaction', 'Transaction'[Revenue]), DISTINCTCOUNT('Transaction'[ID]), 0))
Please refer to sample below:
It’s in Quarter level now. When I focus on 35007, I can see that its “avg revenue” is 300. When I focus on 35002, I can see that its “avg revenue” is 200. This is what you said “where 35002 should be 66% of 35007”.
If I drill down to Month, the result is correct too. Revenue for 35007 is 700 while Revenue for 35002 is 400.
Thanks for looking into my situation and spending time on it.
Your solution calculates the same result as my 'Avg Rev Per Customer2' calculation, but it doesn't adequately discount the denominator. Also, I'm not looking to slice the data by customer, but to drill down by months, qtrs, and years.
In the example with the revenue replaced with 100 for easy to see results (great suggestion by the way), when drilled by month you should always see an average of 100, by quarter you should always see an average of 300. Your example breaks when drilling to the quarter level.
Does that make sense?
See data of quarter 2 in blue. The total revenue is 1400, the distinct count of ID is 5. Now you will find that the average revenue for quarter 2 should be 280. The average revenue 300 I mentioned above is the for ID 35007 in quarter 2, not for all.
It's not fair to count 35002 as the same as 35003 on the denominator. Our business is subscription based which measures different than traditional point of sale. It's more of a weighted average by month, than a true average.
Distinct count gives 35002 and 35003 both the same value (1), but 35002 wasn't around for the same amount of time as 35003. It was only around for 2/3 of the quarter. Where 35003 was around for 3/3 of the quarter.
To get out the data you want, you need to add records for those missing month with "Revenue" blank.
Just like table below. I called it "Transaction2".
Now you can create a measure:
avgRevenue = CALCULATE(DIVIDE(sumx('Transaction2', 'Transaction2'[Revenue]), COUNT('Transaction2'[Revenue]), 0) * COUNTROWS(Transaction2) / DISTINCTCOUNT(Transaction2[ID]))
This is the result:
well as you note a little trial & error is involved, and it depends somewhat on the type of visual you prefer as to what its embedded capabilities are in terms of offering periodic values..... but I would suggest considering adding 2 columns to your transaction table via the query editor:
quarter (values 1 thru 4)
rather than derive these in the calculations
if they exist in the transaction table then they are there for you to use as part of the visual sum/avg/etc features along with ID and revenue....
this might help ......
Check out the November 2023 Power BI update to learn about new features.
Read the latest Fabric Community announcements, including updates on Power BI, Synapse, Data Factory and Data Activator.
Join us for a free, hands-on Microsoft workshop led by women trainers for women where you will learn how to build a Dashboard in a Day!
130+ sessions, 130+ speakers, Product managers, MVPs, and experts. All about Power BI and Fabric. Attend online or watch the recordings.