Power BI Learning Lab

Context Transition and Row Evaluation Context

A real-life commission example. Watch each salesperson row create a row context, then see CALCULATE() convert it into filter context on the Orders table.

Calculated Column
Rep Sales = SUM(Orders[Amount])

Without CALCULATE, the current row does not filter the Orders table.

Salesperson Dimension

Current row highlighted
Rep Region Commission % Calculated Column

Orders Fact Table

Rows lit = visible to the expression

Why context transition matters

Same row context, different result
Without CALCULATE()
$0

The Orders table is not filtered by the active salesperson row.

With CALCULATE()
$0

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 situations

1. 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])
Rule of thumb: if DAX is standing on one row but you want an aggregation to behave as if that row has filtered the model, you need context transition. In explicit DAX this usually means CALCULATE(). In a calculated column that calls a measure, the measure reference already brings an implicit CALCULATE(), so the transition happens automatically.