This lesson on Evaluation Context in DAX: Filter Context vs Row Context is hands-on and example-driven. You will master the foundational mechanics of DAX evaluation by distinguishing between row context and filter context, tracing how filters propagate across relationships, and overriding filter contexts using CALCULATE. You will also learn to extract and inspect the underlying DAX queries generated by visual matrices using Performance Analyzer and DAX Studio.
What You'll Be Able To Do
- Differentiate programmatic row context from visual filter context in calculations.
- Calculate multi-coordinate aggregations dynamically across matrix rows and columns using iterators.
- Modify active filter contexts by applying targeted predicate overrides inside CALCULATE.
- Trace directional filter propagation across one-to-many relationships from dimensions to fact tables.
- Extract and evaluate visual engine queries using Performance Analyzer and DAX Studio.
Detailed Concept Walkthrough
1. Row Context vs Filter Context
Filter context determines which subset of data is visible across the data model, whereas row context exists solely to evaluate expressions row-by-row during table iteration.
- Mechanism: Filter context acts as a model-wide sieve applied automatically by visual headers, slicers, and report filters before any formula evaluates. It filters entire tables down to active subsets across relationships.
- Execution Flow: Row context is created natively in calculated columns or explicitly via iterator functions like SUMX. It loops through a specific table row-by-row to evaluate an expression for the current record only.
- Under the Hood: A row context does not filter other tables or even other rows in the same table automatically. It simply exposes the column values of the single current row being iterated.
- Best Practice: Never assume that putting a field on a visual matrix row creates a row context; visual coordinates generate filter context that aggregates multiple underlying data rows.
// Row context is created internally by SUMX to iterate rows
// Filter context restricts the Sales table to only rows matching the active filters
Sales Amount =
SUMX(
Sales,
Sales[Quantity] * Sales[Net Price]
)
Key Takeaway: Filter context decides what rows are visible to the model; row context iterates over those visible rows one at a time.
2. Multi-Dimensional Filter Context Intersection
Every cell in a Power BI visual evaluates inside a distinct coordinate system formed by the intersection of all applicable row, column, slicer, and report-level filters.
- Mechanism: When placing Product[Brand] on rows and Date[Year] on columns in a matrix, a single cell computes its value within the logical AND intersection of both filters.
- Execution Flow: The DAX engine translates visual matrix coordinates into a table query via SUMMARIZECOLUMNS, grouping values and injecting respective filter sets per coordinate.
- Under the Hood: Iterators like SUMX only iterate over the physical fact rows remaining after this multi-dimensional coordinate intersection has restricted the underlying table.
- Best Practice: Use DAX Studio and Performance Analyzer to capture visual queries and inspect the exact SUMMARIZECOLUMNS structure generating cell contexts.
// DAX Studio query representation of a visual matrix intersection
EVALUATE
SUMMARIZECOLUMNS(
Product[Brand],
Date[Year],
"Sales Amount", [Sales Amount]
)
Key Takeaway: Each visual cell is calculated in isolation under the strict intersection of all active row, column, and slicer filter coordinates.
3. Modifying Filter Context with CALCULATE
CALCULATE is the primary engine function capable of modifying, overriding, or adding to the active filter context before an expression evaluates.
- Mechanism: CALCULATE evaluates its filter arguments in the outer filter context and applies them as new or overriding filters to create a modified context for its inner expression.
- Execution Flow: When a filter predicate like Customer[Continent] = "Europe" is supplied, CALCULATE replaces any existing filter on Customer[Continent] and intersects with all other active filters.
- Under the Hood: The modified filter context propagates down to all related tables before the aggregated measure expression is computed.
- Best Practice: Encapsulate common business logic in base measures (e.g., [Sales Amount]) and reuse them inside CALCULATE to avoid redundant DAX formulas.
// Injects a new filter on Customer[Continent] into the existing filter context
Europe Sales =
CALCULATE(
[Sales Amount],
Customer[Continent] = "Europe"
)
Key Takeaway: CALCULATE modifies the active filter context before evaluating its expression, overwriting or extending outer filters.
4. Directional Filter Context Propagation
Filters naturally propagate across relationships in a star schema from the one-side (dimension) down to the many-side (fact).
- Mechanism: When a dimension table like Product or Customer is filtered, the engine follows the active relationship arrows to reduce the rows visible in the related Sales fact table.
- Execution Flow: Filter context travels unidirectionally by default; filtering the fact table directly does not filter related dimension tables without explicit cross-filtering.
- Under the Hood: The VertiPaq engine leverages relationship column mappings to translate dimension row selections into filtered row indices on the fact table instantly.
- Best Practice: Maintain clean star schema designs with single-direction relationships from dimensions to facts to ensure predictable filter flow.
// Filtering a dimension automatically reduces the fact table (Sales)
// via the 1-to-many relationship: Date[Date] -> Sales[OrderDate]
EVALUATE
CALCULATETABLE(
Sales,
Date[Year] = 2020
)
Key Takeaway: Filter context flows downstream automatically from the 1-side of a relationship to the many-side, restricting related fact rows.
Topics Covered in Evaluation Context in DAX: Filter Context vs Row Context
- Evaluation Context Foundations (0:00 - 1:28) — Establishes the distinction between row context iteration and filter context data filtering using the Contoso model.
- Visual Filters and Iterators (1:28 - 4:48) — Demonstrates how SUMX iterates strictly over the rows visible within the active filter context of a matrix.
- Multi-Dimensional Filter Intersections (4:48 - 6:06) — Shows how row and column visual headers intersect to form composite filter coordinates per cell.
- Matrix Rows vs Row Context (6:06 - 7:37) — Clarifies that visual matrix rows generate filter contexts rather than DAX row contexts.
- Engine Query Inspection (7:37 - 10:01) — Captures and analyzes the SUMMARIZECOLUMNS query generated by Power BI using DAX Studio.
- Filter Modification via CALCULATE (10:01 - 12:15) — Modifies the active evaluation context by injecting new column predicates using the CALCULATE function.
- Filter Context Propagation (12:15 - 13:44) — Traces how filter context travels across one-to-many relationship arrows from dimensions to facts.
Reference Cheat Sheet
-
SUMX— Iterates a table row-by-row evaluating an expressionSUMX(Sales, Sales[Quantity] * Sales[Net Price]) -
CALCULATE— Evaluates an expression under a modified filter contextCALCULATE([Sales Amount], Customer[Continent] = "Europe") -
SUMMARIZECOLUMNS— Generates aggregated query tables across grouped visual coordinatesSUMMARIZECOLUMNS(Product[Brand], "Sales", [Sales Amount]) -
CALCULATETABLE— Evaluates a table expression under modified filter contextCALCULATETABLE(Sales, Date[Year] = 2020) -
Row Context— Identifies the current row during table iterationSales[Quantity] * Sales[Net Price] -
Filter Context— Restricts data model rows visible to expressions
Comparison Table
| Feature | Filter Context | Row Context |
|---|---|---|
| Primary Purpose | Restricts model data visibility | Iterates rows one-by-one |
| Creation Source | Visual coordinates, slicers, CALCULATE | Iterator functions (SUMX), calculated columns |
| Model Propagation | Propagates across relationships | Does not propagate across tables |
| Visual Matrix Row | Generates filter context | Does not exist automatically |
Common Pitfalls
- Mistake: Assuming a visual matrix row creates a DAX row context. Avoid: Recognize visual rows as filter contexts that filter underlying rows to an attribute value.
- Mistake: Expecting fact table filters to automatically filter dimension tables. Avoid: Follow relationship arrows from the one-side to many-side or configure cross-filtering explicitly.
- Mistake: Passing raw table iterations without considering active filter context. Avoid: Remember that iterators like SUMX only iterate rows surviving active filter contexts.
FAQs
- Does placing a field on a visual matrix row create a row context? No, it creates a filter context that filters the underlying data model to that specific field value for aggregation.
- Why does SUMX not iterate over the entire physical table? Iterators only iterate over the subset of rows visible after all active visual and formula filter contexts have been applied.
- How can I see the exact DAX query generated by a visual matrix? Use Performance Analyzer in Power BI Desktop to copy the query, then paste it into DAX Studio to inspect SUMMARIZECOLUMNS.
- Can filter context travel backward from the many-side to the one-side? Not by default; filters flow from the one-side (dimension) to the many-side (fact) unless bidirectional cross-filtering is configured.