Median Product Sales

Share The Knowledge

Some only write measures on data they can see in tables. This is often a bad habit.

Requirement

Calculate the median total sales of all Products.

…or maybe it’s better said this way:

Calculate aggregated sales for each Product. Display the median amount.

Final Visual

A simple single value:

Median sales by product

Set-up

Just two tables for this post:

Final Measure

1step group median = 
MEDIANX(
      SUMMARIZE(
                fctSales,
                fctSales[Product Key],
                "Median Group Sales", CALCULATE(sum(fctSales[Revenue]))
      ),
      [Median Group Sales]
)

1 step measure (uses a virtual table). I compare physical vs virtual solutions below.

Pbix File

Solution Path Review

Now I’ll review two different ways to solve this.

Physical or Virtual?

Table fctSales has individual transactions. To answer the question we need aggregated sales for each Product. How should we aggregate?

  • create a physical aggregated table?
  • create a virtual aggregated table inside the measure?

Physical Table

DAX below creates a physical table:

aggSales =
SUMMARIZE(
    fctSales,
    fctSales[Product Key],
    "SalesByProduct", CALCULATE( SUM( fctSales[Revenue] ) )
)
Table ‘aggSales’

We can see the aggregated amount for each product. What’s the problem?

In large models if we create a table for every intermediary step the file size increases and the data model becomes cluttered.

Final measure ‘addMedian’ references the aggregated column values:

addMedian = MEDIAN(aggSales[SalesByProduct])

Virtual Table

A single measure calculates everything. The final measure, repeated below, contains a virtual table using the SUMMARIZE function.

1step group median = 
MEDIANX(
      SUMMARIZE(
                fctSales,
                fctSales[Product Key],
                "Median Group Sales", CALCULATE(sum(fctSales[Revenue]))
      ),
      [Median Group Sales]
)

The disadvantage is that we can’t see the values inside the virtual table. Testing can be done using DAX Studio (see below).

Virtual tables unleash a world of possibilities. Complex questions can be answered inside a single measure but it takes time to learn.

Solution Pitfall

Using a variable to calculate the sum doesn’t work. Why?

I read somewhere that it calculates when defined and can’t be changed when used later (eg inside SUMMARIZE). Measure below doesn’t work.

1step group median NO =
VAR AllSales =
    CALCULATE( SUM( fctSales[Revenue] ) ) 
//doesn't work as it calcs a single value that can't be changed later on
RETURN
    MEDIANX(
        SUMMARIZE( fctSales, fctSales[Product Key], "Median Group Sales", AllSales ),
        [Median Group Sales]
    )

Measure Testing

DAX Studio

Use DAX Studio to see/test results for each part of a measure without creating excessive tables in the pbix file.

Excellent tutorial: Writing DAX Queries (daxstudio.org)

Connect to Pbix file

I connected to my pbix demo file

Query Syntax

The aggregation part of my measure after keyword EVALUATE. Press the Play button to see the results.

Query and results

Results above are the same as table aggSales (physical table in pbix).

Summary

I occasionally create a table using DAX but it should be an exception not a rule.

It takes me a long time to understand some requirements. I’m getting better at translating them into the DAX language.

Learning DAX Studio does require practice but it’s worth it as there are so many benefits. And it’s free!


Share The Knowledge

Leave a Reply

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