Gyromitra Inc.
← Back to Blog

Study Guide

Row Context vs Filter Context: The DAX Concept Most Candidates Fail

By Dr. Rosario Feghali · July 31, 2026 · 8 min read

Ask a room of PL-300 candidates to define "filter context" and most can give a reasonable answer. Ask them to explain why the same-looking formula behaves differently in a calculated column versus a measure, and the room goes quiet. That gap — knowing the term but not the mechanics — is exactly where this exam catches people, and it's the single concept I spend the most time on in every cohort.

This post is the explanation I wish someone had given me before I had to work it out from documentation.

The two contexts, defined properly

Row context is "which row am I currently looking at." It exists whenever DAX is evaluating an expression one row at a time — inside a calculated column, or inside an iterator function like SUMX, FILTER, or AVERAGEX. In row context, DAX knows the values of every column in that row, and nothing else.

Filter context is "which rows are currently visible to me, out of the whole table." It's built up from everything filtering your visual: slicers, visual-level filters, page filters, relationships propagating from other tables, and any CALCULATE filter arguments in your formula. A measure is always evaluated inside a filter context, even if that context is "no filters at all."

They sound similar because both restrict which data an expression sees. The difference is how they restrict it: row context is one row at a time, positional; filter context is a set of visible rows, defined by conditions. Confusing the two is where almost every intermediate-level DAX mistake comes from.

Why a calculated column and a measure behave differently

This is the example that makes it click. Say you have a Sales table with UnitPrice and Quantity columns, and you write this as a calculated column:

Line Total = Sales[UnitPrice] * Sales[Quantity]

This works exactly as expected — for every row, DAX multiplies that row's price by that row's quantity. That's row context doing exactly what it's for: the calculation is anchored to a specific row, and it's computed once, at refresh time, and stored.

Now write the same expression as a measure:

Line Total (Measure) = SUM(Sales[UnitPrice]) * SUM(Sales[Quantity])

Notice this isn't even the same formula — you can't write Sales[UnitPrice] * Sales[Quantity] directly as a measure, because a measure has no row context to anchor to. It only has filter context: whatever rows are currently visible, it aggregates across all of them. That's why measures are built from aggregation functions (SUM, AVERAGE, COUNTROWS) — you have to tell DAX how to collapse a set of rows into one number, because there's no "current row" to reference.

This is the first thing to internalize: calculated columns compute in row context and store a value per row; measures compute in filter context and calculate on the fly, per visual. Reaching for the wrong tool — a calculated column where a measure was needed, or vice versa — is one of PL-300's favourite wrong-answer traps.

Where it gets genuinely tricky: iterators mix both

Iterator functions (anything ending in XSUMX, AVERAGEX, FILTER, RANKX) are where row context and filter context meet, and where most confusion happens.

Total Revenue =
SUMX(
    Sales,
    Sales[UnitPrice] * Sales[Quantity]
)

SUMX iterates the Sales table row by row — inside that iteration, you're in row context, so Sales[UnitPrice] * Sales[Quantity] resolves per row exactly like a calculated column would. But SUMX as a whole is still a measure, evaluated inside whatever filter context the visual provides. The filter context determines which rows Sales contains when SUMX starts iterating; the row context then applies within that already-filtered set.

So the sequence is: filter context narrows the table down to the relevant rows, then row context walks through them one at a time. Get comfortable with that ordering — filter first, then row — because case-study questions often describe a scenario and ask you to predict what an SUMX or FILTER expression returns under specific slicer conditions.

The reverse direction: context transition

The trickier direction is a measure reference inside row context — say, inside a calculated column, or inside an iterator:

Revenue Contribution =
Sales[Line Total] / [Total Revenue]

If this is a calculated column, Sales[Line Total] resolves fine in row context. But [Total Revenue] is a measure — it needs filter context, not row context. DAX handles this automatically: whenever a measure (or a CALCULATE) is evaluated inside a row context, DAX converts that row context into an equivalent filter context, applying the current row's column values as filters. This is context transition, and it's what makes [Total Revenue] inside this calculated column return the total revenue for rows matching this row's values rather than the grand total across the whole table — which is rarely what you want, and a common source of "why is my calculated column wrong" bugs.

This is also why calculated columns that reference measures can be slow: context transition runs once per row, which on a large table means the measure's full filter-context evaluation runs thousands or millions of times during refresh.

A quick way to check yourself

When you're staring at a DAX formula and need to know what context you're in, ask:

  • Are you inside a calculated column, or an iterator's row-by-row argument? → row context.
  • Are you inside a measure, evaluated by a visual, with no active iteration? → filter context.
  • Are you referencing a measure (or CALCULATE) from inside row context? → context transition just converted your row context into a filter context.

Almost every DAX debugging session I run with students comes down to identifying which of these three situations they're actually in, because the formula that "should" work often does — it's just evaluating in a context the author didn't expect.

What PL-300 actually tests

The exam rarely asks you to define row context or filter context in isolation. It tests this through scenario questions: given a calculated column or measure and a description of the report, predict the output, or identify why a value is wrong and pick the fix. Those questions are answerable quickly once you can name which context you're in at each step of the formula — which is the whole point of walking through the mechanics above rather than memorizing the vocabulary.

Want to work through DAX context problems like these every week?

Gyromitra's PL-300 membership pairs the full self-paced course with a live weekly Q&A with a Microsoft Certified Trainer — bring your own row-context-vs-filter-context questions. Join anytime, no cohort to wait for.