Microsoft Power BI Quiz: Row Vs Filter Context
15 questions · exam conditions
0:00
Row Vs Filter ContextQuestion 1 of 15

Inside nested SUMX iterators, EARLIER refers to which context?

The current row context
The previous row context
The current filter context
The inner row context
← Back to quizzes

Microsoft Power BI Quiz

Microsoft Power BI Quiz: Row Vs Filter Context

Practice Row Vs Filter Context in Microsoft Power BI with focused quiz questions that help you check what you know, review explanations, and build confidence with test-style prompts.

What this quiz covers

This quiz focuses on Row Vs Filter Context, giving you a quick way to practice the rules, question types, and explanations that matter most for Microsoft Power BI.

How to use this quiz

Try each quiz question before looking at the correct answer. Use the explanations to review missed ideas, then come back to similar questions until the pattern feels familiar.

All questions

Question 1

Inside nested SUMX iterators, EARLIER refers to which context?

  1. The current row context
  2. The previous row context (correct answer)
  3. The current filter context
  4. The inner row context
Explanation: In nested iterators like two SUMX loops, EARLIER returns the row context of the outer loop while the inner loop is evaluating. That means it looks back to the previous row context, not the current inner one. The tempting wrong choice is the current row context, but within the inner iterator the current context is the inner row; EARLIER steps outside it to the enclosing loop.

Question 2

A slicer filters Product[Category]. How does a Sales measure see the selection?

  1. A filter context on Sales (correct answer)
  2. A filter on Product only
  3. A row context on Product
  4. A row context on Sales
Explanation: The slicer filters Product[Category], and that filter propagates across the relationship from Product to Sales. So when the Sales measure calculates, it sees a filter context on Sales that restricts which sales rows are included. The tempting wrong answer is that the filter stays on Product only, but relationships pass the filter down to the related Sales table.

Question 3

Context transition converts a row context into what?

  1. A row context on that row
  2. A row context on the table
  3. A filter context on that row (correct answer)
  4. A filter context on the table
Explanation: Context transition, triggered by CALCULATE, takes the current row context and creates a filter context that restricts the table to that row. That is why measures inside row contexts can see only the current row's values. The tempting wrong choice is a filter context on the whole table: the filter is table-level in mechanics, but its scope is only the current row, not all rows.

Question 4

A calculated column uses RELATED to pull a value. Which context evaluates it?

  1. Neither row nor filter context
  2. Filter context only, not row
  3. Both contexts, row and filter
  4. Row context only, not filter (correct answer)
Explanation: A calculated column is evaluated row by row, and RELATED reads the related table through that row context. Filter context applies only to measures, not to calculated columns. The tempting mistake is thinking both contexts apply, but slicers and filter panes do not change the value in a calculated column.

Question 5

In SUMX(Table, Expression), where is the row context applied?

  1. Only in the table argument
  2. Only in the second argument (correct answer)
  3. In both arguments equally
  4. In neither argument at all
Explanation: SUMX iterates over the table in the first argument and creates a row context, but that row context is applied while evaluating the expression in the second argument. The first argument just provides the rows; it isn't evaluated per row. The tempting wrong answer is that both arguments use the row context equally, but only the expression inside SUMX sees the current row.

Question 6

A report filter leaves three products visible. Their sales amounts are 120120, 8080, and 00. The [Sales Amount] measure is defined as SUM(Sales[Amount]).

You create this measure:

Test Total = SUMX(VALUES(Product[ProductKey]), SUM(Sales[Amount]))

What value will Test Total return, and why?

  1. It returns 200200 because each product row created by SUMX automatically filters Sales through the relationship.
  2. It returns 600600 because the naked SUM sees the original filter context and repeats 200200 for each product row. (correct answer)
  3. It returns 400400 because products without sales are excluded before SUMX evaluates its expression.
  4. It returns 00 because SUM cannot be evaluated inside an iterator unless CALCULATE is explicitly used.
Explanation: When you see SUMX paired with a naked SUM (no CALCULATE) inside the iterator, you need to think carefully about filter context vs. row context — one of the most tested DAX concepts on the Power BI exam. Here's what actually happens: SUMX(VALUES(Product[ProductKey]), SUM(Sales[Amount])) iterates over three product keys. On each iteration, SUMX creates a row context — it "knows" which product row it's on — but a row context does not automatically filter related tables. Without CALCULATE, the inner SUM(Sales[Amount]) never transitions that row context into a filter context. So instead of seeing only one product's sales, it sees the full report filter context each time, which includes all three products totaling 200200. It evaluates 200200 three times, producing 200×3=600200 \times 3 = 600. That confirms B is correct. A is wrong because it assumes that iterating over a product key automatically filters the Sales table through the relationship — this only happens when row context is converted via CALCULATE. Without it, no such transition occurs. C is wrong on two counts: it invents a filtering step that doesn't exist, and 400400 has no logical basis in the actual computation. D is wrong because SUM can be evaluated inside an iterator — it just doesn't transition row context without CALCULATE. The function runs fine; it simply returns the unfiltered total each time. Study tip: Memorize this pattern — naked aggregates inside SUMX ignore the iterator's row context. Whenever you want the iterator to filter related tables, you must wrap the inner expression in CALCULATE.

Question 7

The Product table contains many colors. You add this calculated column to the table:

Copied Color = SELECTEDVALUE(Product[Color], "Multiple")

Every row displays Multiple, even though each product has one color.

Which change best produces the current row's color while demonstrating the relevant context behavior?

  1. Use CALCULATE(SELECTEDVALUE(Product[Color], "Multiple")) so context transition makes the current product row a filter. (correct answer)
  2. Use FILTER(Product, Product[Color] = Product[Color]) so the calculated column receives a filter context for one color.
  3. Use ALLSELECTED(Product[Color]) so the current row context is converted directly into a scalar color value.
  4. Use SUMX(Product, SELECTEDVALUE(Product[Color])) so the iterator returns the color associated with the current row.
Explanation: Whenever you see a calculated column behaving unexpectedly in DAX, think about row context vs. filter context. A calculated column runs in row context — it iterates each row — but SELECTEDVALUE requires a filter context to isolate a single value. Without a filter context, DAX sees the entire Product table as the current context, finds multiple colors, and returns the alternate result ("Multiple") every time. The fix is context transition, which is exactly what CALCULATE triggers. When you wrap an expression in CALCULATE inside a calculated column, DAX automatically converts the current row context into an equivalent filter context — effectively filtering the table to just the current row. This means SELECTEDVALUE(Product[Color], "Multiple") now sees only one color per row and returns it correctly. That makes A the right answer: it uses CALCULATE to perform context transition, which is precisely the behavior the question asks you to demonstrate. B is wrong because FILTER returns a table, not a scalar, and the self-referencing condition Product[Color] = Product[Color] is always true, so it doesn't isolate a single row anyway. C is wrong because ALLSELECTED removes filters rather than creating them — it expands context instead of narrowing it to the current row. D is wrong because SUMX with SELECTEDVALUE on a text column is semantically broken; SUMX aggregates numeric values, and iterating the entire Product table doesn't isolate one row for a calculated column context. Study tip: Anytime SELECTEDVALUE or VALUES returns unexpected results in a calculated column, your first instinct should be "I need CALCULATE for context transition."

Question 8

A model contains a single Sales table. A report page directly filters Sales[Region] to West and Sales[Year] to 2025. You define:

High Value Sales = CALCULATE(SUM(Sales[Amount]), FILTER(ALL(Sales), Sales[Amount] > 1000))

Which statement correctly describes how the expression is evaluated?

  1. FILTER tests rows from only West in 2025 because row context always inherits every filter removed by ALL.
  2. FILTER scans all sales rows in row context, and its resulting table becomes filter context for the calculation. (correct answer)
  3. ALL creates row context for every sales row, while FILTER converts that row context into the final scalar result.
  4. CALCULATE preserves the West and 2025 filters because Boolean conditions inside FILTER can remove only amount filters.
Explanation: When you see a question involving CALCULATE and ALL together, focus on how filter context is established, removed, and replaced — that's the core DAX mechanic being tested here. ALL(Sales) removes every filter currently on the Sales table, including the report's West and 2025 filters. FILTER then iterates over that unrestricted table row by row — this is row context — testing whether Sales[Amount] > 1000. The resulting table (all rows where Amount exceeds 1000, regardless of region or year) is handed back to CALCULATE as a new filter context, replacing the original filters. So B correctly captures the sequence: FILTER scans all rows via row context, and its output table becomes the filter context for SUM. A is wrong because it inverts the logic of ALL. ALL explicitly removes existing filters rather than inheriting them — there is no mechanism by which row context "re-inherits" filters that ALL discarded. C misattributes what creates row context. ALL returns a table; it doesn't create row context. Row context is created by FILTER as it iterates that table, not by ALL itself. FILTER also doesn't produce a scalar — it returns a filtered table. D is wrong because CALCULATE does not preserve the West and 2025 filters here. ALL(Sales) overrides them entirely, and Boolean filter arguments in CALCULATE don't selectively protect certain column filters. A useful rule of thumb: ALL wipes filters, FILTER creates row context while iterating, and the table FILTER returns becomes the new filter context inside CALCULATE. Keep that sequence memorized for any DAX filter-context question.

Question 9

A table visual contains Sales[OrderLineID], which uniquely identifies each sales row. You attempt to create this measure:

Large Line = IF(Sales[Amount] > 1000, 1, 0)

The expression produces a single-value error in contexts where more than one amount is visible.

Which statement best explains why placing the measure in the table visual does not inherently solve the problem?

  1. A visual row establishes both contexts, but numeric columns must always be wrapped in SUMX when used in an IF expression.
  2. A visual row establishes row context, but measures discard it unless the expression is enclosed within CALCULATE.
  3. A visual row establishes filter context, not DAX row context; the measure still needs an aggregation or scalar-selection function. (correct answer)
  4. A visual row establishes neither context; only calculated columns can respond to fields placed in a report visual.
Explanation: Whenever you see a DAX question mixing measures with column references, pause and ask yourself: which type of context is actually present here? DAX has two distinct evaluation contexts — row context (created by iterators or calculated columns, which moves row-by-row through a table) and filter context (created by slicers, visual rows, and CALCULATE, which narrows the visible data). When a table visual places Sales[OrderLineID] in rows, it creates a filter context per row — it filters the Sales table to show only rows matching that OrderLineID. It does not create row context. Your measure IF(Sales[Amount] > 1000, 1, 0) directly references a column, which requires row context to resolve to a scalar. Inside a measure with only filter context, DAX sees potentially multiple values in Sales[Amount] and throws a single-value error. The fix is wrapping the column reference in a scalar-selection function like MAX, MIN, or SELECTEDVALUE, so DAX always receives one number. This is why C is correct. A is wrong because there is no rule requiring SUMX specifically for IF expressions — SUMX is an iterator, useful when you need to loop, but it's not the only or mandatory solution here. B is wrong because it misidentifies the missing piece. Measures don't "discard" row context and then recover it with CALCULATECALCULATE transforms filter context, it doesn't create row context inside a measure. D is wrong because visuals absolutely do establish filter context; calculated columns aren't the only constructs that respond to report fields. As a study habit, always distinguish "filter context narrows rows" from "row context iterates rows" — confusing the two is the most common DAX trap on the Power BI exam.

Question 10

The Sales table is on the many side of an active many-to-one relationship with Product. You create this calculated column in Sales:

Product Segment = RELATED(Product[Segment])

Why can RELATED return one segment for each sales row without an explicit CALCULATE?

  1. The relationship propagates the sales row's row context to Product, after which an implicit iterator retrieves the first segment.
  2. The calculated column automatically converts every sales row into filter context before any relationship function is evaluated.
  3. RELATED creates filter context over all product rows and uses SELECTEDVALUE internally to choose the visible segment.
  4. The calculated column's row context supplies the current sales row, and RELATED follows its relationship key to the one-side row. (correct answer)
Explanation: When you see a question about RELATED or DAX context, anchor your thinking around two distinct concepts: row context and filter context, and how relationships interact with each. In a calculated column, DAX automatically establishes a row context — it iterates through every row in the table, giving you access to each row's column values one at a time. When your calculated column lives in Sales (the many-side), RELATED exploits the existing active relationship by following the foreign key from the current sales row to its matching single row on the Product (one-side) table. It then reads Product[Segment] directly from that matched row. No CALCULATE is needed because RELATED is specifically designed to traverse relationships within a row context — that's its entire purpose. This makes D the correct answer. A is wrong because relationships don't "propagate row context" — that's not how DAX works. Row context doesn't travel across relationships automatically; only RELATED (or RELATEDTABLE) bridges that gap explicitly. B is wrong because calculated columns do not automatically convert row context into filter context. That conversion requires CALCULATE. Confusing these two contexts is one of the most common DAX mistakes. C is wrong on multiple counts: RELATED doesn't create filter context, and it doesn't call SELECTEDVALUE internally. RELATED works within row context, not filter context, and it returns exactly one value because the relationship guarantees a single matching row on the one-side. Study tip: Memorize this pairing — RELATED works with row context on the many-side; RELATEDTABLE works on the one-side to return a table. If a question mentions crossing a relationship in a calculated column, think RELATED + row context immediately.

Question 11

A report filters the Sales table to the East region. You define:

Weighted Revenue = SUMX(FILTER(Sales, Sales[Quantity] >= 2), Sales[Quantity] * Sales[NetPrice])

Which description correctly identifies how row context and filter context interact in this measure?

  1. FILTER ignores the East filter because every iterator replaces filter context with row context over the entire source table.
  2. FILTER scans East-region rows in row context, and SUMX uses row context to multiply columns for qualifying rows. (correct answer)
  3. FILTER converts the East filter into row context, while SUMX converts qualifying rows back into the original filter context.
  4. SUMX requires CALCULATE around the multiplication because column references cannot use an iterator's row context directly.
Explanation: When you see a question about DAX iterators like SUMX or FILTER, focus on two distinct concepts working in layers: filter context (which rows exist in the model for a given evaluation) and row context (the current row an iterator is examining one at a time). Here's how the measure actually executes. The report's East region filter is already active as filter context before the measure even begins — it restricts Sales to East rows only. FILTER then iterates over those already-filtered rows, establishing a row context for each one to evaluate Sales[Quantity] >= 2. Rows passing that condition form a smaller table. SUMX then iterates that smaller table in its own row context, multiplying Sales[Quantity] * Sales[NetPrice] row by row and summing the results. This is exactly what B describes: FILTER scans East-region rows in row context, and SUMX uses row context to compute the multiplication for qualifying rows. A is wrong because iterators do not replace or ignore existing filter context — they add a row context on top of it. The East filter remains fully active. C inverts the relationship incorrectly; FILTER doesn't "convert" filter context into row context and SUMX doesn't restore it — both iterators operate within the existing filter context while creating their own row contexts. D is false because column references like Sales[Quantity] and Sales[NetPrice] are perfectly valid inside an iterator's row context without needing CALCULATE. A reliable study tip: think of filter context as the room you're in, and row context as walking through that room one step at a time — iterators walk, they don't redecorate the room.

Question 12

You create the following calculated column in Product:

Price Rank = 1 + COUNTROWS(FILTER(Product, Product[ListPrice] > EARLIER(Product[ListPrice])))

How are the two references to Product[ListPrice] resolved while FILTER evaluates a product row?

  1. Both references use the inner FILTER row context, so the comparison is always false and every product receives rank one.
  2. The first reference uses filter context, while EARLIER retrieves the most recent report-level filter on list price.
  3. The first reference uses the inner row context, while EARLIER retrieves the price from the outer calculated-column row context. (correct answer)
  4. The first reference uses the outer row context, while EARLIER retrieves the price from the inner FILTER row context.
Explanation: Whenever you see EARLIER in a DAX calculated column, you're being tested on nested row context — specifically, how DAX tracks multiple simultaneous row contexts when one iterating function is nested inside another. Here's what happens when this calculated column evaluates a single product row (call it Product A with a price of $50): DAX establishes an outer row context for Product A. Then FILTER begins iterating every row in the Product table, creating an inner row context for each row it visits. Inside that inner context, Product[ListPrice] naturally resolves to the current inner row's price — whatever product FILTER is examining right now. But you still need to compare against Product A's price. That's exactly what EARLIER does: it steps back one context level and retrieves the value from the outer calculated-column row context, giving you Product A's $50. The formula then counts how many products are priced higher than Product A, producing a descending price rank. This confirms C as correct. The first Product[ListPrice] resolves to the inner FILTER row context, while EARLIER(Product[ListPrice]) retrieves the outer context's price. A is wrong because the two references do not both use the inner context — EARLIER explicitly escapes it. B is wrong because EARLIER has nothing to do with filter context or report-level filters; it strictly navigates row context levels. D reverses the roles entirely — it's the first reference that is inner, not outer, and EARLIER that is outer, not inner. As a study tip, remember: EARLIER always means "one row context level up." When you see it nested inside FILTER within a calculated column, there are exactly two row context levels, and EARLIER retrieves the outermost one.

Question 13

A model contains a Customer table on the one side of a one-to-many relationship with a Sales table. You create the following calculated column in Customer:

Lifetime Sales = SUM(Sales[Amount])

During refresh, the column displays the same grand total for every customer. You are considering changing the expression to:

Lifetime Sales = CALCULATE(SUM(Sales[Amount]))

Why does the revised expression return sales for the current customer?

  1. CALCULATE converts the current customer's row context into filter context, which then propagates through the relationship to Sales. (correct answer)
  2. CALCULATE creates a new row context over Sales, causing SUM to aggregate only rows related to the current customer.
  3. SUM automatically follows relationships only when it is nested inside CALCULATE, regardless of the evaluation context.
  4. CALCULATE replaces the current customer's row context with a row context on each related row in the Sales table.
Explanation: Whenever you see a DAX question involving calculated columns, you need to think carefully about evaluation context — specifically the difference between row context and filter context, and how CALCULATE bridges them. In a calculated column, DAX automatically establishes a row context, meaning the formula evaluates once per row. When you write SUM(Sales[Amount]) directly in the Customer table, DAX has a row context (the current customer row) but SUM doesn't know to filter Sales by that customer — it simply aggregates the entire Sales table, producing the same grand total on every row. This is the core problem. Answer A is correct because CALCULATE performs a crucial operation called context transition: it converts the current row context into an equivalent filter context. That filter context — "this specific customer" — then propagates through the existing relationship into Sales, so SUM only sees rows belonging to that customer. This is why adding CALCULATE with no explicit filter arguments is enough to fix the formula. Answer B is wrong because CALCULATE never creates a new row context over Sales. Context transition produces a filter context, not a row context — these are fundamentally different concepts. Answer C is wrong because SUM has no special relationship-following behavior that activates inside CALCULATE. Relationships are leveraged through filter context propagation, not through SUM itself. Answer D is wrong because CALCULATE doesn't replace one row context with another row context on Sales. Again, the mechanism is conversion to filter context, not substitution of row contexts. Study tip: Memorize this pattern — in a calculated column, wrapping an expression in CALCULATE with no filters triggers context transition, transforming row context into filter context. This is one of the most tested DAX nuances on the Power BI exam.

Question 14

The [Sales Amount] measure returns sales in the current filter context. You define:

Product Average = VAR CurrentSales = [Sales Amount] RETURN AVERAGEX(VALUES(Product[ProductKey]), CurrentSales)

When evaluated for a category, the result equals the category's total sales rather than the average of its product sales.

Which explanation and correction are most appropriate?

  1. The variable is evaluated once in category filter context; place [Sales Amount] directly inside AVERAGEX to evaluate it per product. (correct answer)
  2. The variable is recalculated for every iterator row; wrap CurrentSales in SUM to preserve each product's row context.
  3. AVERAGEX removes category filter context before iterating; replace VALUES with ALLSELECTED to restore the category total.
  4. VALUES creates filter context rather than row context; replace it with FILTER so the variable changes for each product.
Explanation: Whenever you see a question involving DAX variables inside iterators like AVERAGEX, the core concept to test is variable evaluation timing — specifically, when and where a variable's value is "locked in." In DAX, a variable is evaluated exactly once, at the point it is defined, capturing the filter context that exists at that moment. In this measure, CurrentSales is defined outside AVERAGEX, so it captures [Sales Amount] under the category filter context. When AVERAGEX iterates over each product, it doesn't re-evaluate CurrentSales — that value is already frozen. As a result, every iteration returns the same category total, and averaging identical values just returns that same total. The fix is straightforward: move [Sales Amount] directly inside AVERAGEX, so it evaluates fresh for each product row with the combined row and filter context that AVERAGEX creates per iteration. That makes A the correct answer. B is wrong because variables are never recalculated per iterator row — that's precisely the misconception this question targets. Wrapping CurrentSales in SUM wouldn't change that frozen value at all. C is wrong because AVERAGEX doesn't strip filter context before iterating. The category filter context remains intact; the problem is the variable, not the iterator's behavior with filters. D is wrong because VALUES returns a table used for iteration — it doesn't "create filter context." Replacing it with FILTER doesn't address the real issue of when [Sales Amount] is evaluated. Study tip: On Power BI DAX questions, whenever a variable appears inside an iterator, ask yourself: was this variable defined before or inside the iterator? If before, it's frozen — move calculations inside the iterator to get row-level evaluation.

Question 15

A matrix displays Product[Category] and then Product[ProductName]. You define:

Percent of Category = DIVIDE([Sales Amount], CALCULATE([Sales Amount], REMOVEFILTERS(Product[ProductName])))

At a product-name row, which contexts determine the denominator?

  1. REMOVEFILTERS creates row context over category products, so the denominator is an average of their sales.
  2. CALCULATE removes the entire product row context, so the denominator is sales across every product category.
  3. REMOVEFILTERS clears only row context from the matrix, so the denominator remains the current product's sales.
  4. CALCULATE removes the product-name filter but retains the category filter, so the denominator is category sales. (correct answer)
Explanation: When you use CALCULATE with REMOVEFILTERS in DAX, you need to think carefully about which filters get removed and which ones survive. The filter context in a matrix visual is built layer by layer — the category filter applies first, then the product-name filter narrows it further. In DIVIDE([Sales Amount], CALCULATE([Sales Amount], REMOVEFILTERS(Product[ProductName]))), the REMOVEFILTERS(Product[ProductName]) call removes only the filter on the ProductName column. Critically, it leaves the Category filter intact. So at any product-name row, the denominator resolves to total sales for that product's parent category — exactly what you'd want for a "percent of category" calculation. That makes D correct. A is wrong because REMOVEFILTERS has nothing to do with row context or averages. It modifies filter context, and it never produces an average of anything on its own. B is wrong because REMOVEFILTERS(Product[ProductName]) is column-specific — it does not wipe out all product filters. If you wanted the denominator to be grand-total sales, you'd need REMOVEFILTERS(Product) or ALL(Product) targeting the entire table. C is wrong in two ways: REMOVEFILTERS operates on filter context, not row context, and it does change the filter — it removes the product-name filter rather than leaving it unchanged. Study tip: Always ask yourself "which column or table am I passing to REMOVEFILTERS?" The scope of what gets cleared is exactly as narrow as the argument you provide. When only a column is specified, every other filter on that table remains active.