• Zur Hauptnavigation springen
  • Zum Inhalt springen
  • Zur Seitenspalte springen
  • Zur Fußzeile springen

THE SELF-SERVICE-BI BLOG

Wir lieben Microsoft Power BI

  • Videokurse
    • Coming soon!
  • Live Online Power BI-Schulungen
  • Beratung
    • Was ich für Dich tun kann
    • Showcases
  • Kunden
  • BLOG
    • Business Topics
    • Technical Topics (english)
    • Tools
  • Podcast
  • Kontakt
  • Über

Technical Topics (english) / 11. November 2019

How does the filter context in DAX apply?

If you deal with Time Intelligence functions (TI) in DAX, you quickly reach the point where you can no longer use the standard TI functions. Very quickly you reach the ingenious site (daxpatterns.com) of Marco and Alberto from SQLBI, where they among other things show patterns for custom TI functions. The current article uses the TI pattern as an example to show how the filter context works, but this can generally be transferred to the functionality in DAX.

How the pattern looks like

Custom TI functions can be useful and necessary if the standard TI functions of DAX are no longer sufficient. The pattern from SQLBI looks as follows:

[SalesYTD] :=
CALCULATE (
    [Sales],
    FILTER (
        ALL ( ‚Date‘ ),
        ‚Date'[Year] = MAX ( ‚Date'[Year] ) &&
        ‚Date'[Date] <= MAX ( ‚Date'[Date] )
    )
)

https://www.daxpatterns.com/time-patterns/

What the pattern does

Let’s try to follow the pattern by using the (green highlighted) example value 3rd of January 2018:

The TI pattern and the existing filter context, DAX, Power BI, Power Pivot
The TI pattern and the existing filter context

The pattern does the following:

  1. The FILTER function is an iterator. It iterates over the complete and unfiltered Calendar table row by row, because ALL( ‚Calendar‘) is ignoring the existing filters of the filter context (the date 3rd of January 2018) on the Calendar table.
  2. Due to the existing row context created by the FILTER function, it iterates over each row in the Calendar table and compares two things:
    1. If the given ‚Year‘ (marked red) is equal to the maximum ‚Year‘ (marked green) respecting the current filter context (which is 3rd of January 2018) and
    2. if the given ‚Date‘ (marked red) is smaller than or equal to the maximum ‚Date‘ (marked green) of the current filter context (which again is 3rd of January 2018).
  3. At the end, when all filters are set, the measure [Sales] is evaluated.

Now please answer the following question: Why is MAX( 'Calendar'[Year] ) and MAX( 'Calendar'[Date] ) evaluated under the existing »filter context«? Take some time and see if you can find a satisfactory answer.

Why it works

I have been using this pattern for a very long time and simply accepted that it works without really asking myself why it works. There is this already very old but wonderful article by Jeffrey Wang (read my interview with him here) which describes how cross filtering works in DAX. He describes that there are only 3 ‚targets of filter context‘ in the DAX language:

  1. A table reference (like ‚Sales‘),
  2. VALUES( Table[Column] ) and
  3. DISTINCT( Table[Column] ).

Nothing else gets effected by the filter context. But how does that relate to the TI pattern of our Italian friends, as neither MAX( 'Calendar'[Year] ) nor MAX( 'Calendar'[Date] ) contain one of the 3 targets from above?

It’s all about syntax sugar

Since DAX was developed for business users, „the original design goal was to make syntax as simple as possible in common usage patterns while maintaining a coherent and semantically sound language model“ (quote Jeffrey Wang, from my interview with him). That’s why there is so much ’syntax sugar‘ in DAX, which means that a more complex DAX expression is hidden in a simpler one.

I think that most DAX users know that
=
CALCULATE ( [Total Sales], Product[Color] = „Red“ )

is internally converted to

=
CALCULATE (
[Total Sales],
    FILTER ( ALL ( Product[Color] ), Product[Color] = „Red“ ).
)

just to make the DAX entry point for beginners easier. The same applies to all aggregate functions that accept a column reference such as Table[Column] as the only argument, such as SUM( Table[Column] ) and also MAX( Table[Column] ). Jeffrey describes it in the above mentioned blog article as follows:

Note that DAX function Sum(T[C]) is just a shorthand for SumX(T, [C]), the same is true for other aggregation functions which take a single column reference as argument. Therefore the table in those aggregation functions is filtered by filter context.

Good bye syntax sugar

Armed with this knowledge, let’s have a look at the TI pattern without syntax sugar:

The TI pattern without syntax sugar, Power BI, DAX, Power Pivot
The TI pattern without syntax sugar

Since each MAX( Table[Column] ) expression is represented internally by MAXX( Table, Table[Column] ), the circle closes here: The first parameter of MAXX() is a table reference and this belongs to the 3 targets of the filter context. All this can of course be transferred to all other DAX expressions.

And now to be honest, was that the answer you would have given me to my question?! 😉

Cheers from Germany,

Lars

Lars Schreiber

Lars ist Berater, Entwickler und Trainer für Microsoft Power BI. Er ist zertifizierter Power BI-Experte und Microsoft Trainer. Für sein Engagement in der internationalen Community wurde Lars seit 2017 jährlich durch Microsoft der MVP-Award verliehen. Lies hier mehr…

Kategorie: Technical Topics (english) Stichworte: Data Analysis eXpressons, DAX

Leser-Interaktionen

Kommentare

  1. Sumit Malik meint

    30. April 2020 um 3:43 pm

    Hi Lars,
    Hope you are doing well.
    Even, I am still not able to understand why/how MAX is working in current filter context

    Could you please provide me some link, from where I can get DAX from very basics
    As per my understanding FILTER ALL – Returns all table and after that on complete table below filter is applied
    Date'[Year] = MAX ( ‚Date'[Year] ) &&
    ‚Date'[Date] <= MAX ( ‚Date'[Date]

    So when this logic runs for filter context 03.01.2018, then from full table we will pick all date which are = MAX ( ‚Date'[Year] )

    2) what is MAXX how it work, SUMX iterate row by row and SUM, how MAXX works?

Seitenspalte

WEBSITE DURCHSUCHEN

MELDE DICH FÜR DIE POWER BI USER GROUP HAMBURG AN

Trage Deine E-Mailadresse ein, um für kommende Treffen der PUG Hamburg eingeladen zu werden. Zudem erhältst Du Zugriff auf die Materialien der vergangenen Treffen.

Footer

Kontakt

THE SELF-SERVICE-BI BLOG
Mail: lars@ssbi-blog.de

Rechtliches

  • Impressum
  • Datenschutz

Über THE SELF-SERVICE-BI BLOG

Ich bin ein freiberuflicher Power BI-Berater, -Entwickler und -Trainer und wurde von Microsoft mehrfach mit dem MVP Award ausgezeichnet. Ich arbeite mit einem kompetenten Netzwerk aus freiberuflichen und ambitionierten Kollegen zusammen. Erfahre hier mehr.

Social

Folge mir...

Copyright © 2025 · Digital Pro on Genesis Framework