Back to Blog

Power BI Measures - A Practical Guide to DAX for Australian Businesses

May 8, 20268 min readMichael Ridland

Most Power BI reports I've reviewed over the years have one thing in common. They start out clean, then a year later they're full of bizarre column-based hacks because nobody on the team understood measures.

If you only learn one thing about DAX, learn measures. They're the difference between a report that ages well and one that gets rewritten every six months.

This is a walkthrough of what we tell clients about measures, why they matter for business reporting, and the patterns we keep using on real projects across Sydney, Melbourne, and Brisbane.

What a measure actually is

A measure is a calculation that runs every time you interact with a visual. Filter the chart by year, the measure recalculates. Change the slicer to a different region, it recalculates again. That's the bit that makes Power BI feel alive instead of static.

Compare that to a calculated column. Calculated columns get computed once at refresh time and sit in your data model taking up memory. They don't respond to filters in the way most people expect. New analysts almost always reach for calculated columns first because they look more familiar, and they almost always regret it later.

Rule of thumb we use with clients: if the result depends on what the user is looking at, it's a measure. If it's a static property of a row, it might be a column.

The "Projected Sales" example, but real

Microsoft uses a sales projection example in their docs - last year's sales times 1.06. It's fine, but I want to give you something closer to what we actually build.

A typical project we deliver involves a finance team that wants to see revenue, gross margin, and forecast variance, sliced by product, region, salesperson, and time. They have a fact table for sales, another for budget, and dimension tables for customer, product, and date.

Here's the kind of measure set we'd build:

Total Revenue = SUM(Sales[Amount])

Total Cost = SUM(Sales[Cost])

Gross Margin = [Total Revenue] - [Total Cost]

Gross Margin % = DIVIDE([Gross Margin], [Total Revenue])

Budget Revenue = SUM(Budget[Amount])

Revenue vs Budget = [Total Revenue] - [Budget Revenue]

Revenue vs Budget % = DIVIDE([Revenue vs Budget], [Budget Revenue])

Notice the pattern. Build base measures first. Then build derived measures on top of them. Don't repeat SUM(Sales[Amount]) in fifteen places. If the business changes how revenue is defined (and they will), you update one measure and everything else updates with it.

We've inherited models where every visual had its own copy of the same formula. Cleaning that up takes weeks. Don't be that team.

Report-level vs model-level measures

Power BI lets you create measures inside a report rather than the model itself. Useful in two scenarios:

You're connecting to a published dataset or Fabric semantic model and you need a one-off calculation for your specific report. The model owner doesn't have to publish it for everyone.

You're prototyping. Build it as a report measure, see if it sticks, promote it to the model later if the business actually uses it.

The honest assessment: report-level measures are convenient but they multiply. We've seen organisations where the same "YTD Revenue" measure exists in twelve different reports, all slightly different. If you're going to use them, have a governance plan. Otherwise everything that should live in the model eventually does, just in a chaotic distributed way.

For most of our Power BI consulting engagements, we push for a single well-governed semantic model with measures that are reviewed and named consistently. Report measures are for genuine one-offs.

Time intelligence is where DAX earns its keep

The single biggest reason to bother with DAX is time intelligence. Comparing this month to last month, year-to-date, rolling 12, same period last year - these are everywhere in business reporting and they're miserable to do in SQL.

Revenue YTD =
TOTALYTD([Total Revenue], 'Date'[Date])

Revenue Same Period Last Year =
CALCULATE([Total Revenue], SAMEPERIODLASTYEAR('Date'[Date]))

Revenue Rolling 12 =
CALCULATE(
    [Total Revenue],
    DATESINPERIOD('Date'[Date], MAX('Date'[Date]), -12, MONTH)
)

These work because you have a proper date table marked as a date table in the model. If you've ever wondered why your time intelligence "isn't working", that's usually the reason. Build a date table, mark it as a date table, relate it to your fact tables on the date column. The tutorials skip this step constantly and it causes endless pain.

Where teams go wrong

A few patterns we see repeatedly:

Using calculated columns when measures would work. If you want a column that shows "Above Target" or "Below Target" for each row, you can do it with a calculated column. But the moment you want that classification to respond to a slicer (say, the target changes based on selected region), the calculated column is wrong. It was set at refresh and doesn't know about the slicer. Use a measure with SWITCH(TRUE(), ...) logic instead.

Repeating SUM everywhere. Build base measures. Reference them in derived measures. Save your future self.

Not using DIVIDE. Plain / blows up on divide-by-zero. DIVIDE returns blank by default, which is almost always what you want in a visual. Small thing, big impact on whether reports keep working.

Hiding columns but not the calculations table. If you build a dedicated "Measures" table, hide the placeholder column but leave the table visible. Easy to mess up.

Inline complex logic. A measure with eight nested CALCULATEs that nobody can read is technical debt. Break it into pieces. Comment the why. We've handed back models where the previous consultant left a single 200-line measure with no documentation. Don't do that.

Quick measures - useful, but read the DAX

Quick Measures in Power BI Desktop generate DAX from a dialog. They're genuinely good for two things. First, they get you a working calculation in 30 seconds. Second, they show you the DAX they generated, which is the fastest way to learn the syntax of less common patterns.

But the generated DAX is often more verbose than what you'd write yourself. Treat Quick Measures as a starting point. Refactor the output before it goes into production.

Organising measures so you can find them

Once you've got 40 measures, finding the right one becomes a problem. A few things help.

Use a dedicated measures table. Create an empty table called something like "_Measures" (the leading character floats it to the top of the fields list), move all your measures into it, hide the column.

Use display folders. In Model view, set the Display Folder property on measures so they group together. We typically have folders like "Revenue", "Costs", "Margins", "Time Intelligence", "Variance", and so on. You can nest folders with backslashes.

Name measures consistently. "Total Revenue", "Total Cost", "Total Margin" reads better than "Revenue", "CostSum", "GP Total". Boring consistency beats clever variation every time.

Honest opinions on DAX

DAX is more powerful than it looks and harder than it looks. The basic syntax is comfortable for anyone with Excel experience, which lulls people into thinking they understand it. Then they hit row context vs filter context, and CALCULATE, and EARLIER, and suddenly nothing makes sense.

If you're building anything beyond basic sums and averages, invest in learning row context and filter context properly. The book "The Definitive Guide to DAX" by Russo and Ferrari is still the reference. We hand it to every analyst we work with.

On the upside, DAX rewards investment. Once it clicks, you can build calculations that would take 200 lines of SQL in a single measure. The semantic model approach (define it once, use it everywhere) is genuinely good.

The flip side: DAX errors are cryptic. Performance issues require understanding the storage engine. Some patterns that look identical perform 100x differently. This is the part where having someone who's been through it before saves you weeks of trial and error.

How this fits the bigger picture

Measures matter most when Power BI is the analytical layer over a broader data platform. The pattern we recommend for most mid-sized Australian businesses:

Get your data into a Fabric or Azure-based warehouse or lakehouse. Build a clean semantic model on top. Measures live in the semantic model. Reports consume measures rather than recreating them.

This way, the finance, sales, and operations teams all see the same "Revenue" number because they're all reading the same measure. That sounds obvious but it's wildly uncommon in practice.

If you're earlier in your data journey, our Power BI consultants and broader Microsoft Fabric work is mostly about getting the foundation right so the measures you build today don't need to be rewritten next year.

A short reading list

If you want help building or auditing a Power BI model, that's the kind of work we do every week. Get in touch and we'll have a look at what you've got.