variable
variable

Reputation: 9664

In the CALCULATE function, how are filters applied when more than 1 filter expression is provided?

In the CALCULATE function, how are filters applied when more than 1 filter expression is provided?

Example:

CALCULATE(expr, filter1, filter2)

The 1st filter takes the entire filter context (all the tables involves in the relation) and applies filter1 to it. Then it does the same for the 2nd filter separately. Then it intersects boths the above results and performs the calculation expression on the resultant dataset?

I am confused because if the above is true, then how does using VALUES override any filters applied (for example using ALL)?

Upvotes: 0

Views: 580

Answers (2)

sergiom
sergiom

Reputation: 4877

CALCULATE function is executed as a sequence of steps. A very good explanation of these steps can be found on dax.guide site page for CALCULATE

  1. CALCULATE evaluates all the explicit filter arguments in the original evaluation context. This includes both the original row contexts (if any) and the original filter context. All explicit filter arguments are evaluated independently in the original evaluation context. Once this evaluation is finished, CALCULATE starts building the new filter context.
  2. CALCULATE makes a copy of the original filter context to prepare the new filter context. It discards the original row contexts, because the new evaluation context will not contain any row context.
  3. CALCULATE performs the context transition. It uses the current value of columns in the original row contexts to provide a filter with a unique value for all the columns currently being iterated in the original row contexts. This filter may or may not contain one individual row. There is no guarantee that the new filter context contains a single row at this point. If there are no row contexts active, this step is skipped. Once all implicit filters created by the context transition are applied to the new filter context, CALCULATE moves on to the next step.
  4. CALCULATE evaluates the CALCULATE modifiers used in filter arguments: USERELATIONSHIP, CROSSFILTER, ALL, ALLEXCEPT, ALLSELECTED, and ALLNOBLANKROW. This step happens after step 3. This is very important, because it means that one can remove the effects of the context transition by using ALL as a filter argument. The CALCULATE modifiers are applied after the context transition, so they can alter the effects of the context transition.
  5. CALCULATE applies the explicit filter arguments evaluated at 1. to the new filter context generated after step 4. These filter arguments are applied to the new filter context once the context transition has happened so they can overwrite it, after filter removal — their filter is not removed by any ALL* modifier — and after the relationship architecture has been updated. However, the evaluation of filter arguments happens in the original filter context, and it is not affected by any other modifier or filter within the same CALCULATE function. If a filter argument is modified by KEEPFILTERS, the filter is added to the filter context without overwriting existing filters over the same column(s).

assuming to have a CALCULATE expression like

CALCULATE( [Sales], 'Product'[Color] = "Red", 'Product'[Brand] = "Contoso" )

then the [Sales] measure is evaluated in a filter that takes the products that are "Red" and which brand is "Contoso". Both filters are evaluated in step #1 and later applied during step #5.

if instead the expression is

CALCULATE( [Sales], 'Product'[Color] = "Red", ALL( 'Product'[Brand] ) )

first the 'Product'[Color] = "Red" filter is evaluated for step #1, then for step #4 the ALL modifier is applied, removing any existing filter over 'Product'[Brand] and later for step #5 the filter evaluated in step #1 over 'Product'[Color] is applied

Since the filter is evaluated in step #1 and applied in step #5, it's possible to use VALUES to save an existing filter to be applied after the step #4, where filters might be removed.

Assuming that a filter over 'Product'[Brand] exists when this CALCULATE is evaluated

CALCULATE( [Sales], ALL( 'Product' ), VALUES( 'Product'[Brand] ) )

what happens is that in step #1 VALUES( 'Product'[Brand] ) is evaluated, saving the existing filter over 'Product'[Brand], then in step #4 the ALL( 'Product' ) modifier removes any existing filter over the whole 'Product' table and finally the step #5 applies back the filter over 'Product'[Brand] that was evaluated in step #1

The ALL() VALUES() pattern is explained in detail in this article Using ALLEXCEPT versus ALL and VALUES

Upvotes: 2

mkRabbani
mkRabbani

Reputation: 16908

You can try this below syntax-

total =
CALCULATE(
    SUM(table_name[column_name]),
    FILTER(
        ALL(table_name),
        table_name[filter_column_name1] = "ABC"
        && table_name[filter_column_name2] = 10
    )
)

Upvotes: 0

Related Questions