Every DAX formula evaluates in a filter context — the current row, selection, and slicer state. Usually, that is exactly what you want. However, some calculations need to look outside the current row and compare it against all other rows in the table. EARLIER makes this possible. It captures an outer row’s column value for use inside an inner iteration.
The most common use case is ranking: how many rows have a higher value than this one? EARLIER answers that inside COUNTROWS or FILTER. This guide explains what EARLIER does and why row context nesting requires it. Six practical examples follow. Topics include running totals, percentile bands, ranking, and per-category comparisons.
What Problem Does EARLIER Solve?
When DAX evaluates a calculated column, it iterates row by row. Inside that loop, you can access the current row’s columns. However, if your formula contains a FILTER that iterates the same table again, a second inner row context is created. At that point, the outer row’s values are replaced by the inner iteration’s current row.
EARLIER solves this by capturing the column value from the outer context. The name reflects its purpose: EARLIER means an earlier, outer evaluation context. EARLIER(Sales[Amount]) returns the outer loop’s Amount, not the inner loop’s.
| Expression | Which row’s value is returned |
|---|---|
| [Amount] | The current (innermost) row being evaluated |
| EARLIER([Amount]) | The value from the next outer row context (one level up) |
| EARLIEST([Amount]) | The outermost row context (two or more levels up) |
VAR CurrentAmount = Sales[Amount] before the FILTER expression. Then reference CurrentAmount inside the filter. Variables are easier to read and behave the same way. Use EARLIER when working in environments that do not support variables.How Do You Write an EARLIER Formula?
EARLIER only works in calculated columns, not in measures. Measures do not have a row context in the same sense — they aggregate across a filter context. Calculated columns, on the other hand, are computed row by row, which is exactly the nested-iteration scenario EARLIER is designed for.
= COUNTROWS(FILTER(Sales, Sales[Amount] > EARLIER(Sales[Amount])))Examples 1–4: EARLIER in Practice
The most classic EARLIER use case is ranking. For each row, count how many other rows have a higher sales amount. Adding 1 gives the rank: if zero rows have a higher value, this row is rank 1.
Ranking across the entire table treats all rows together. Ranking within a category requires an additional filter on the same category. For each row, count only the rows in the same Product that have a higher amount. This produces a within-group rank rather than an overall rank.
A running total sums all rows up to and including the current row’s date. EARLIER captures the current date, and FILTER selects all rows with a date on or before that date. SUMX then totals the Amount for that filtered subset.
Comparing each row to the overall average does not need EARLIER in a measure, but in a calculated column it requires capturing the current row’s amount for comparison. EARLIER stores the row value while AVERAGEX computes the whole-table average in a clean single expression.
Examples 5–6: Percentile Bands and Multi-Level Context
EARLIER combined with COUNTROWS can assign each row to a percentile band. First, rank each row (as in Example 1). Then divide the rank by the total row count to get a percentile position. A nested IF then classifies the row into Top, Mid, or Bottom band.
When a calculated column formula nests three levels of row iteration — for example, a FILTER inside a SUMX inside another FILTER — EARLIER only goes back one level. EARLIEST skips to the outermost context. This is rare in practice but useful when building hierarchical scoring models that iterate at two nested levels simultaneously.
Common Issues and How to Fix Them
EARLIER returns an error in a measure
EARLIER requires a row context to exist. Measures execute in filter context, not row context. Consequently, using EARLIER in a measure produces a "EARLIER/EARLIEST refers to an earlier row context which doesn’t exist" error. The fix is to move the logic to a calculated column, or rewrite it as a measure using RANKX instead of COUNTROWS+FILTER+EARLIER for ranking scenarios.
Results are incorrect when rows share the same value
When multiple rows have identical values, the COUNTROWS+EARLIER approach assigns the same rank to all tied rows. This is standard dense-rank behaviour. The next rank number after a tie is skipped. For example, if three rows tie for rank 2, the next rank is 5, not 3. To produce standard competition ranking (1, 2, 2, 4), use RANKX instead. RANKX has built-in tie-handling options that EARLIER does not provide natively.
Frequently Asked Questions
-
What does EARLIER do in DAX?+EARLIER captures the value of a column from an outer row context and makes it available inside an inner row iteration. When a calculated column formula contains a FILTER or SUMX that iterates the same table, two row contexts are active simultaneously. EARLIER lets you reference the outer row’s column value inside the inner loop. The most common use is ranking: counting how many rows have a higher value than the current row by using EARLIER to hold the current row’s value while FILTER scans all rows.
-
Can I use EARLIER in a measure?+No. EARLIER only works in calculated columns. Measures do not have a row-by-row context in the same way — they are evaluated in filter context across a set of rows. Using EARLIER in a measure produces an error. For measure-level ranking, use RANKX instead. RANKX is specifically designed to work in filter context and handles ties through built-in tie options.
-
What is the difference between EARLIER and VAR for row context?+Both capture the outer row value for use inside an inner expression. EARLIER does this implicitly by telling DAX to look up one level in the row context stack. VAR does this explicitly by assigning the value to a named variable before the inner expression. VAR is preferred in modern DAX because the code reads more clearly — you can give the variable a descriptive name — and it works in both calculated columns and measures. EARLIER is used in older Excel versions where VAR is unavailable.
-
When should I use RANKX instead of EARLIER for ranking?+Use RANKX when you need ranking in a measure, when you need to rank across a different table than the one being filtered, or when you need built-in tie-handling options (Dense, Skip). Use EARLIER+COUNTROWS in a calculated column only when you need the rank as a persistent column value or when combining the rank logic with other per-row calculations in the same expression. RANKX is more flexible and performant on large tables in most ranking scenarios.