Salesperson Dimension
Current row highlightedOrders Fact Table
Rows lit = visible to the expressionWhy context transition matters
Same row context, different resultThe Orders table is not filtered by the active salesperson row.
The current salesperson row becomes a filter on Orders[RepID].
Mental model
Row context tells DAX which row it is currently evaluating.
Filter context determines which rows are visible to aggregation.
CALCULATE() is the bridge between them.
When Should You Use Context Transition?
Practical DAX situations1. In a measure
In measures, you usually use context transition when an iterator creates row context and you need a measure or aggregation to evaluate for the current iterated row.
- Use it inside
SUMX,AVERAGEX,FILTER, or similar iterators when each row must become a filter. - If you only need a plain aggregation over already filtered rows, context transition is not the point.
- The usual tool is
CALCULATE(), because it converts the current row context into filter context.
High Value Customers :=
COUNTROWS(
FILTER(
Customers,
CALCULATE( SUM(Orders[Amount]) ) > 30000
)
)2. In a calculated column
A calculated column already has row context, but row context alone does not filter related fact rows. Use context transition when the current row must drive an aggregation over another table.
- Without
CALCULATE(),SUM(Orders[Amount])will often see too many rows. - With
CALCULATE(), the current dimension row is pushed into filter context. - This is common when building per-customer, per-product, or per-salesperson summary columns.
Customer[Customer Sales] =
CALCULATE(
SUM(Orders[Amount])
)3. In a calculated column, when calling a measure
This is the subtle one. A measure always needs filter context to produce a value. If you call a measure inside a calculated column, DAX wraps that measure call in an implicit CALCULATE. That means context transition happens automatically.
- There is row context because the column is being computed row by row.
- The measure call triggers implicit context transition.
- So the current row can become filter context even though you did not type
CALCULATE()yourself.
[Total Sales] := SUM(Orders[Amount])
Customer[Sales via Measure] =
[Total Sales]4. When not to use it
Do not force context transition if your business question is already answered by natural filter context from slicers, relationships, or report filters.
- A regular measure like
Total Sales := SUM(Orders[Amount])already works in visuals. - If you create unnecessary calculated columns for dynamic logic, results can become static and misleading.
- Prefer measures for report-time calculations; use calculated columns only when row-by-row stored results are truly needed.
Total Sales :=
SUM(Orders[Amount])CALCULATE(). In a calculated column that calls a measure, the measure reference already brings an implicit
CALCULATE(), so the transition happens automatically.