
For Community Month at #WOW2025 towers, Lorna presented a challenge one of her colleagues had brought to her which they solved together. The need is to identify the top X customers in each year (which may not contain the same set of customers each year), and then present the sales contribution, either as a group or individually compared to the rest. Lorna gave a hint in the challenge that sets would help : “Your job is to figure out the best way to SET this up with the last 3 years dynamically”.
It took me a bit of a while to figure out how to make this work, and at the point of writing, haven’t looked at the solution to know if there was a better way. I ultimately ended up creating 3 sets to fulfil this challenge.
Setting up the parameters
This challenge requires 3 parameters
pTop
This identifies how many ‘top’ customers we want to consider. Defined as an integer from 10 to 100, defaulted to 20, that increments every 10 units

pShowCustomers
Determine whether the top customers’ contributions are displayed individually or as a group. Defined as a boolean, defaulted to False, and aliased to Yes or No

pPercentofTotal
Indicate whether the information is displayed as a % of total sales for that year, or as absolute sales values. Defined as a boolean, defaulted to True, and aliased to Yes or No.

Defining the core calculations
The requirement states to be able to determine the last 3 years ‘dynamically’. For this I created
Max Date
{FIXED: MAX([Order Date])}
to return the maximum Order Date in the whole data set.
We want to be able to restrict the data to the last 3 years, so create
Records to Show
DATEDIFF(‘year’, [Order Date], [Max Date]) <=2
I need to create a set for each of the 3 cohorts – the top customers for the latest year, the top for the previous year and the top for the year before that. For this I first need to determine the Sales for each of those timeframes.
The sales for the current year
Sales – CY
IF YEAR([Order Date]) = YEAR([Max Date]) THEN [Sales] END
The sales for the previous year
Sales – PY
IF YEAR([Order Date]) = YEAR([Max Date])-1 THEN [Sales] END
and the sales for the previous previous year
Sales – PPY
IF YEAR([Order Date]) = YEAR([Max Date])-2 THEN [Sales] END
I can then create the sets of customer I need (right click on Customer ID > Create > Set)
Customer ID Set – CY
get the Top number of records using the pTop parameter, and based on the sum of the Sales – CY field

Repeat the same process to create
Customer ID Set – PY
get the Top number of records using the pTop parameter, and based on the sum of the Sales – PY field
and
Customer ID Set – PPY
get the Top number of records using the pTop parameter, and based on the sum of the Sales – PPY field
To verify/understand what we’ve created, on a new sheet
- Add Customer ID to Rows
- Add Order Date to Columns at the Year level as a discrete (blue) pill
- Add Records to Show to Filter and set to True.
- Add Sales to Text.
- Sort by the 2024 Sales value descending.
- Add Customer ID Set – CY to Rows.
You should see the first 20 rows (assuming you haven’t changed the pTop value, display as In

If you now change the sort to sort by 2023 Sales descending, and swap the Customer ID Set – CY with the Customer ID Set – PY, you’ll get the same

So now that’s understood, we want to tag each of our customers based on the year of the order, whether they’re in the top n or not, and whether we want to display the customers individually or not
Group – Detail
IF (YEAR([Order Date]) = YEAR([Max Date]) AND [Customer ID Set – CY]) THEN
IF [pShowCustomers] THEN [Customer ID]
ELSE ‘Top N’
END
ELSEIF (YEAR([Order Date]) = YEAR([Max Date])-1 AND [Customer ID Set – PY]) THEN
IF [pShowCustomers] THEN [Customer ID]
ELSE ‘Top N’
END
ELSEIF (YEAR([Order Date]) = YEAR([Max Date])-2 AND [Customer ID Set – PPY]) THEN
IF [pShowCustomers] THEN [Customer ID]
ELSE ‘Top N’
END
ELSE
‘Other’
END
We’re also going to want to count customers, so need
Count Customers
COUNTD([Customer ID])
On a new sheet add Order Date at the year level as a discrete (blue) to Rows and add Group Detail to Rows too. Add Records to Display to Filter and set to True. Add Sales and Count Customers into the table. Show the pTop and pShowCustomers parameters
When pShowCustomers is set to No, you should just see 2 groupings per year

When set to Yes, you’ll get the Customer IDs listed

Note – the Sales numbers should reconcile to the solution – the count might not, which I believe is due to the solution counting distinct Customer Names rather than Customer ID.
To finalise the core calculations we need to build the initial viz, we have a different display depending whether we’re displaying the absolute or % Sales values.
Create
Sales % Total
SUM([Sales]) / TOTAL(SUM([Sales]))
format to decimal to 2 dp and add into table, adjusting the table calculation so it is computing by the Group – Detail only, so the percentage per year is being displayed.

Then we need
Measure to Plot
IF [pPercentofTotal] THEN [Sales % Total]
ELSE SUM([Sales])
END
format this to a number to 2 dp (just so you can see it has a value) and add to the table, applying the same table calculation settings. Display the pPercentofTotal parameter and flip between to see the column change.

Building the Viz
On a new sheet, add Records to Show to filter and set to True. Add Order Date at the year level as a discrete (blue) pill to Rows. Add Group – Detail to Detail. Change the mark type to bar. Add Measure to Plot to Columns and adjust the table calculation, so it’s computing just by Group-Detail.

Ste the sheet to fit width and show the 3 parameters.
Create a new field
Group – Top N
IF (YEAR([Order Date]) = YEAR([Max Date]) AND [Customer ID Set – CY]) THEN ‘Top N’
ELSEIF (YEAR([Order Date]) = YEAR([Max Date])-1 AND [Customer ID Set – PY]) THEN ‘Top N’
ELSEIF (YEAR([Order Date]) = YEAR([Max Date])-2 AND [Customer ID Set – PPY]) THEN ‘Top N’
ELSE ‘Other’
END
and add to Colour, adjusting the colours to suit. You’ll then need to update the table calculation of the Measure to Plot field to ensure Group – Top N is also checked.

We need to display labels, but these need to differ based what measure we’re showing, and the format is different, so create
Label – % Total
IF [pPercentofTotal] THEN [Sales % Total] END
format this to % with 1 dp and
Label – Sales
IF NOT([pPercentofTotal]) THEN [Sales] END
format this $ K to 1 dp.
Add both of these to the Label shelf and ensure they are listed directly side by side. Only 1 will ever actually display.

Change the pShowCustomers to Yes, and then add a white border via the Colour shelf. Add a Sort to the Group – Detail pill to sort by Sales ascending.

Add Sales, Sales % Total and Count Customers to the Tooltip shelf. additionally create
Tooltip – Customer
IF [pShowCustomers] AND [Group – Detail] <> ‘Other’ THEN [Customer Name] END
and add this to Tooltip too. Adjust the Tooltip to suit (make sure Sales % Total) is computing by both Group – Top N and Group – Detail so has the correct numbers.
Finally, hide the axis (uncheck show header on the Measure to Plot pill) and hide the Order Date label (right click and hide field label for columns).
Then add the sheet to a dashboard, and arrange the parameters suitably.
My published viz is here.
Happy vizzin’!
Donna










































































