Recently I had to write a DAX formula containing a LASTDATE within the logical condition of a FILTER: I found that its behavior was not the one I expected and I further investigated. At the end, I wrote my findings in this article on SQLBI, which can be applied to any Time Intelligence function with a <dates> argument.

The key point is that when you write

LASTDATE( table[column] )

in reality you obtain something like


which converts an existing row context into a filter context.

Thus, if you have something like

FILTER( table, table[column] = LASTDATE( table[column] )

the FILTER will return all the rows of table, whereas you probably want to use

FILTER( table, table[column] = LASTDATE( VALUES( table[column] ) ) )

so that the existing filter context before executing FILTER is used to get the result from VALUES( table[column] ), avoiding the automatic expansion that would include a CALCULATETABLE that would hide the existing filter context.

If after reading the article you want to get more insights, read the Jeffrey Wang’s post here.

In these days I’m speaking at SQLRally Nordic 2012 in Copenhagen and I will be in Cologne (Germany) next week for a SSAS Tabular Workshop, whereas Alberto will teach the same workshop in Amsterdam one week later. Both workshops still have seats available and the Amsterdam’s one is still in early bird discount until October 3rd!

Then, in November I expect to meet many blog readers at PASS Summit 2012 in Seattle and I hope to find the time to write other article on interesting things on Tabular and PowerPivot. Stay tuned!

Context transition

Returns last non blank date.

LASTDATE ( <Dates> )


Returns a table that has been filtered.

FILTER ( <Table>, <FilterExpression> )

Context transition

Evaluates a table expression in a context modified by filters.

CALCULATETABLE ( <Table> [, <Filter> [, <Filter> [, … ] ] ] )


When a column name is given, returns a single column table of unique values. When a table name is given, returns a table with the same columns and all the rows of the table (including duplicates) with the additional blank row if present.

VALUES ( <TableNameOrColumnName> )