Row context vs. filter context in DAX: the essential distinction
DAX has two types of evaluation context that determine how an expression is calculated. Confusing them is the main source of errors for DAX beginners — and even for experienced professionals.
Row context
It occurs when DAX iterates row by row over a table. It exists in calculated columns and in iterator functions such as SUMX, AVERAGEX, FILTER.
-- Calculated column (row context)
Margin = fSales[Revenue] - fSales[Cost]
Here, fSales[Revenue] and fSales[Cost] refer to the values of the current row.
Filter context
It occurs in measures. When a visual applies filters (by date, category, region), those filters create a filter context that restricts the visible rows before the measure is evaluated.
-- Measure (filter context)
Total Sales = SUM(fSales[Revenue])
-- SUM only calculates the rows visible in the current context
The classic mistake
Using a column reference inside a measure as if it were row context:
-- WRONG in a measure:
Wrong Margin = fSales[Revenue] - fSales[Cost]
-- Error: ambiguous column reference in measure
To iterate in measures, use X functions:
-- CORRECT:
Total Margin = SUMX(fSales, fSales[Revenue] - fSales[Cost])
Context transition
When a measure is called within a row context (e.g. inside SUMX), DAX automatically converts the row context into a filter context — this is called context transition. It is powerful but can cause unexpected behavior if not anticipated.
Conclusion
Mastering row and filter context is the foundation for writing correct DAX. Before writing any expression, ask yourself: "am I operating row by row or over a filtered set?" The answer determines the correct approach.