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

LASTDATE( CALCULATETABLE( VALUES( table[column] ) ) )

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!

LASTDATE
Context transition

Returns last non blank date.

LASTDATE ( <Dates> )

FILTER

Returns a table that has been filtered.

FILTER ( <Table>, <FilterExpression> )

CALCULATETABLE
Context transition

Evaluates a table expression in a context modified by filters.

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

VALUES

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 caused by an invalid relationship if present.

VALUES ( <TableNameOrColumnName> )