5.1 DAX Fundamentals and Measures
Key Takeaways
- DAX (Data Analysis Expressions) is the formula language for Power BI measures, calculated columns, and calculated tables.
- Measures are dynamic, evaluated at query time in the current filter context, and are not stored row-by-row.
- Replace implicit measures (drag-and-drop auto-aggregations) with explicit DAX measures for consistency, formatting, and reuse.
- Variables (VAR/RETURN) improve readability, compute a value once even if referenced many times, and aid debugging.
- Row context exists in calculated columns and iterators (SUMX); filter context exists in measures and is set by visuals, slicers, and filters.
Quick Answer: DAX measures are dynamic formulas that calculate on the fly based on the user's filter selections (filter context). Unlike calculated columns, measures are not stored in the model; they compute at query time. Always create explicit measures instead of relying on implicit auto-aggregations, and use VAR/RETURN for readable, efficient formulas.
What is DAX?
DAX (Data Analysis Expressions) is the formula language used in Power BI for measures (dynamic query-time calculations), calculated columns (row-by-row computations stored in the model), calculated tables (whole tables from expressions), and row-level security rules. DAX is also the language behind Analysis Services tabular models and Power Pivot, so the skills transfer across the Microsoft BI stack.
Measures vs. Calculated Columns
| Feature | Measure | Calculated Column |
|---|---|---|
| Evaluation | At query time (dynamic) | At refresh time (static) |
| Context | Filter context | Row context |
| Storage | Not stored (computed live) | Stored in model (increases size) |
| Use in slicers | No | Yes |
| Use in relationships | No | Yes |
| Responds to filters | Yes | No (fixed value) |
| Best for | Aggregations, ratios, KPIs | Static row-level attributes |
Creating Measures
Syntax is Measure Name = DAX_EXPRESSION.
Total Revenue = SUM(Sales[Amount])
Order Count = COUNTROWS(Sales)
Average Order Value = AVERAGE(Sales[Amount])
Unique Customers = DISTINCTCOUNT(Sales[CustomerID])
Implicit vs. Explicit Measures
Implicit measures are auto-aggregations Power BI applies when you drop a numeric column into a visual (dragging Amount yields "Sum of Amount"). Explicit measures are DAX formulas you author, such as Total Revenue = SUM(Sales[Amount]).
Explicit measures are preferred because they give consistent behavior across every visual, are reusable inside other measures, can be formatted once (currency, percentage), appear in a single predictable location in the field list, and are required for any non-trivial calculation (ratios, time intelligence). In Power BI you can even disable implicit measures at the model level to force explicit ones.
Exam Tip: Know why explicit measures should replace implicit measures. Create an explicit measure for any value that appears in reports.
Filter Context
Filter context is the set of active filters that decide which rows a measure evaluates. It comes from visual fields (axes, legend), slicers, cross-filtering from other visuals, report/page-level filters, and row-level security.
Total Revenue = SUM(Sales[Amount])
| Context | Revenue Calculates Over |
|---|---|
| No filters | ALL sales rows |
| Year slicer = 2026 | Sales where Year = 2026 |
| Year = 2026, Product = Widget | Sales matching both |
| Bar chart by Region | Each bar: that region's sales |
Row Context
Row context exists when DAX iterates rows: calculated columns evaluate per row, and iterator functions (SUMX, AVERAGEX, COUNTX, MAXX, MINX) create row context inside a measure.
Line Total = Sales[Quantity] * Sales[UnitPrice] // calculated column
Total Revenue = SUMX(Sales, Sales[Quantity] * Sales[UnitPrice]) // iterator measure
Variables (VAR / RETURN)
Profit Margin =
VAR TotalRevenue = SUM(Sales[Revenue])
VAR TotalCost = SUM(Sales[Cost])
VAR Profit = TotalRevenue - TotalCost
RETURN
IF(TotalRevenue = 0, BLANK(), DIVIDE(Profit, TotalRevenue))
Variables aid readability, boost performance (a value is computed once even if referenced many times), simplify debugging, and centralize logic. Two rules matter: a variable is evaluated where it is defined (not where referenced), and it is immutable. Because of the evaluation rule, variables capture the filter context at their definition point, which is occasionally surprising inside CALCULATE.
Quick Measures
Quick Measures (Home > Quick Measure) generate DAX from a guided wizard for running totals, moving averages, YTD, year-over-year, per-category averages, and weighted averages. Inspect the generated DAX to learn the underlying patterns.
On the Exam
The PL-300 tests differentiating measures from calculated columns, understanding filter context, writing basic aggregations (SUM, COUNT, AVERAGE, DISTINCTCOUNT), using VAR/RETURN, and explaining why explicit measures replace implicit ones.
Why Filter Context Is the Whole Game
If you understand filter context deeply, most of DAX falls into place. A measure has no fixed value, it has a different value in every cell of every visual, because each cell imposes its own filter context. A single Total Revenue = SUM(Sales[Amount]) produces the grand total in a card, a per-region figure in a bar chart, a per-month figure on a line chart, and a per-cell figure in a matrix, all without changing the formula. The engine intersects every active filter (axis fields, legend, slicers, cross-filter selections, page and report filters, and row-level security) and evaluates the expression over the surviving rows.
Mastering this means you stop thinking "what does the formula compute" and start thinking "what filter context is this cell in."
Row Context Does Not Filter
A subtle but heavily tested point: row context is not filter context. Inside a calculated column or an iterator, row context gives you access to the current row's values, but it does not automatically filter related tables or measures. That is why a measure placed inside SUMX only behaves per-row because of context transition (the engine wraps it in an implicit CALCULATE), not because row context filters on its own. Confusing the two leads to the classic bug where a calculated column referencing a measure returns the same grand total on every row.
Naming, Formatting, and Organization
Professional models treat measures as first-class citizens. Give them clear business names, set a default format string once on the measure (so every visual inherits it), assign a display folder, and consider a dedicated, hidden "Measures" home table so they are easy to find. These housekeeping steps are not cosmetic, the PL-300 explicitly values a model that delivers a consistent, governed self-service experience, and consistent measure formatting and organization are part of that bar.
What is the key difference between how a measure and a calculated column evaluate?
Why should explicit measures be created instead of relying on implicit measures (auto-aggregations)?
In Total Revenue = SUMX(Sales, Sales[Quantity] * Sales[UnitPrice]), what type of context does SUMX create?
What is true about a DAX variable defined with VAR?