Analysing Customer Sales by RANKX() and What If Parameters

By in ,
1352
Analysing Customer Sales by RANKX() and What If Parameters

In this post I am going to show how to use a combination of RANKX() function and Power BI What-If parameters to analyse the customers’ monthly sales and find out the customers with the best, worst and medium sales growth. The formula I used for sales trend is margin of the current month sales amount to average sales amount during the last 12 months:

Customer Sales Trend= (Current month sales – Average last 12 months) / Average last 12 months

I want to show CustomerName and SalesTrend% in a table visual and able the end users to:

  • Toggle between top and bottom customers.
  • Change the number of the visible customers in the visual (top/bottom N customers)
  • Change the percentage boundary to show the middle customers as well (e.g. from -100% to 100% , -70% to 70%)

You can see the preview of all the above features below:

The model I used for this demo is a simple Sales dataset with 3 tables: Sales, Date and Customer:

First I created a measure to show monthly average of sales amount during the 12 months prior to the selected month by using AverageX and DatesInPeriod functions:

Sales Amount Avg L12M =CALCULATE(
AVERAGEX(VALUES('Date'[Month]),Sales[Sales Amount]) ,
DATESINPERIOD('Date'[Date],DATEADD(FIRSTDATE('Date'[Date]),-1,DAY),
-12, MONTH)
)


Then Sales Trend% can be calculated as margin of Sales Amount to the 12 months average:

Sales Trend% = DIVIDE(Sales[Sales Amount]-Sales[Sales Amount Avg L12M],
Sales[Sales Amount Avg L12M],
BLANK())


We need to create two What-If parameters, one for selecting the number of visible customers:

And one for changing boundaries of SalesTrend%:

We also need a table with one column and two rows to store Top and Bottom values which be used for toggling:

In the report we  create 2 slicers for What-If parameters and a ChicleSlicer (this is a custom visual) for Top-Bottom  based on Direction column in ShowType table:

Now it is the time for creating measures to give us Top/Bottom customers. I start with a simple formula and then evolve it step by step by including the parameters . The below DAX returns top 20 customers how have the highest sales trend:

Sales Trend% Top Customers =
CALCULATE (
Sales[Sales Trend%],
FILTER (
VALUES ( Customer[Customer Name] ),
RANKX (ALL ( Customer[Customer Name] ),Sales[Sales Trend%], , DESC) <= 20
)
)


I should mention the credit of the above formula goes to Sam McKay from Enterprise DNA.

By replacing 20 in the above formula with CustomersToShow[CustomersToShow Value], the number of visible customers will be changed dynamically based on CustomerToShow parameter:

Sales Trend% Top Customers =
CALCULATE (
Sales[Sales Trend%],
FILTER (
VALUES ( Customer[Customer Name] ),
RANKX (ALL ( Customer[Customer Name] ),Sales[Sales Trend%], , DESC) 
<= CustomersToShow[CustomersToShow Value] )
)


And for showing the top customers in a selected sales trend percentage range, Customer[Customer Name] must be filtered inside RANKX and also in the result set:

Sales Trend% Top Customers = 
CALCULATE (
Sales[Sales Trend%], 
FILTER( VALUES ( Customer[Customer Name] ), 
RANKX (
FILTER ( 
ALL(Customer[Customer Name] ), 
Sales[Sales Trend%] >=MIN('SalesTrendBondary'[SalesTrendBondary] )
&& Sales[Sales Trend%] <= MAX ( 'SalesTrendBondary'[SalesTrendBondary] )
),Sales[Sales Trend%], , DESC ) 
<= CustomersToShow[CustomersToShow Value] && 
Sales[Sales Trend%] >= MIN ( 'SalesTrendBondary'[SalesTrendBondary] ) &&
Sales[Sales Trend%] <= MAX ( 'SalesTrendBondary'[SalesTrendBondary] ) 
)
) 

 

Now we need to create another measure for bottom customers. The new measure is similar to the above measure just in RANKX function DESC should be replaced by ASC:

Sales Trend% Bottom Customers = 
CALCULATE (
Sales[Sales Trend%], 
FILTER( VALUES ( Customer[Customer Name] ), 
RANKX (
FILTER (ALL(Customer[Customer Name] ), 
Sales[Sales Trend%] >=MIN('SalesTrendBondary'[SalesTrendBondary] )
&& Sales[Sales Trend%] <= MAX ( 'SalesTrendBondary'[SalesTrendBondary] )
),Sales[Sales Trend%], , ASC ) 
<= CustomersToShow[CustomersToShow Value] && 
Sales[Sales Trend%] >= MIN ( 'SalesTrendBondary'[SalesTrendBondary] ) &&
Sales[Sales Trend%] <= MAX ( 'SalesTrendBondary'[SalesTrendBondary] ) 
)
)


Then create a measure to switch between top and bottom measures based on ShowType[Direction] value:

Sales Trend% Customer = IF(SELECTEDVALUE(ShowType[Direction])="Top",
Sales[Sales Trend% Top Customers]
,Sales[Sales Trend% Bottom Customers])


And finally the calculations  are completed. [Customer Name] and [Sales Trend% Customer] are added to a table visual and by using the slicers we can explore top, bottom and average customers of the month:

Leave a reply

Your email address will not be published. Required fields are marked *