DAX - Kaskadierende Tabellen-Filter

Von Lukas Hillesheim, 5. Februar 2024
Blog Article & Copyright by Lukas Hillesheim
Der folgende Artikel zeigt, wie kaskadierende Aufrufe von CALCULATETABLE dazu verwendet werden können, um einen Filter über mehrere Hops zu transportieren. Mögliche Szenarien hierfür sind Tabellen, die im Galaxy-Schema organisiert sind oder die Teil eines weiter verzweigte Snowflake-Schemas sind.

1. Regeln für die Kaskadierung von CALCULATETABLE

Die filternde Tabelle kann sich auf der 1-Seite oder der N-Seite befinden
Szenario: T1 -> T2
In Szenario 1 existieren zwei Tabellen T1 und T2. Zwischen den beiden Tabellen besteht eine Relationship mit T2 auf der 1-Seite. Die Tabelle, die zum Filtern verwendet wird, kann "oben" - also auf der 1-Seite - liegen, als auch "unten" - also auf der N-Seite. Oder anders ausgedrückt: T1 kann zum Filtern von T2 verwendet werden und umgekehrt.
  • // Die beiden nachfolgenden Statements bewirken eine Übertragung des Filters:
  • CALCULATETABLE ( T2, T1 )
  • CALCULATETABLE ( T1, T2 )
Relationships sind transitiv
Szenario: T1 -> T2 -> T3
Wie im Beispiel oben verweisen die Pfeile jeweils auf die 1-Seite.
  • // Die beiden nachfolgenden Statements bewirken eine Übertragung des Filters:
  • CALCULATETABLE ( T3, T1 )
  • CALCULATETABLE ( T1, T3 )
An der Stelle, wo eine Richtungs-Umkehr stattfindet, muss CALCULATETABLE wiederholt angewandt werden
Szenario: T1 -> T2 <- T3 oder
Szenario: T1 <- T2 -> T3
In beiden Fällen findet bei T2 eine Richtungs-Umkehr statt.
  • // Die beiden nachfolgenden Statements bewirken eine Übertragung des Filters:
  • CALCULATETABLE ( T3, CALCULATETABLE ( T2, T1 ) )
  • CALCULATETABLE ( T1, CALCULATETABLE ( T2, T3 ) )
  • // Die beiden nachfolgenden Statements bewirken KEINE Übertragung des Filters:
  • CALCULATETABLE ( T3, T1 ) )
  • CALCULATETABLE ( T1, T3 ) )
Damit ein Filter kaskadiert werden kann, muss das Start-Objekt bereits gefiltert sein
Diese Regel ist selbstverständlich und sollte nicht erwähnt werden müssen, denn ein Filter, der nicht existiert, kann nicht übertragen werden. Durch die Komplexität der Statements und die Tatsache, dass nicht alle Tabellen-Ausdrücke eine Context Transition durchführen, kann dieser Sachverhalt übersehen werden.

2. Schematisches Bespiel

Ein Filter soll über 7 Hops übertragen werden. Start ist T1, Ende ist T7. Die gelb markierten Objekte zeigen die Punkte, an denen die Relationships ihre Richtung ändern. 
Figure 1: Cascading Filter Systematics
Figure 2: Solution Pattern 1
Figure 3: Solution Pattern 2
Die zweite Variante (Figure 3) stellt sicher, dass der initiale Filter auf T1 erstellt wird.

3. Praxis-Beispiel im Galaxy-Schema

Figure 4: Galaxy Schema
Das Beispiel zeigt 4 Tabellen, die Teil eines Galaxy-Schemas sind:
[Product] <- [FactSales01] -> [Time] <- [FactPlan]
Die Lösung:
Figure 5: Solution
Das Code-Beispiel läßt die Operation an der Tabelle [Product] starten:
  • EVALUATE(
  • ADDCOLUMNS(VALUES('Product'[ProdName]) ...

Measure bzw. Computed Column [SumActualAmount]

Da [Product] und [FactSales01] in einer direkten Beziehung zueinander stehen, wird mit Hilfe von CALCULATE aus der jeweiligen Produkt-Zeile ein Filter erstellt und auf die Tabelle [FactSales01] übertragen.
Die zusätzliche Einschränkung auf das Jahr 2018 wurde in das Beispiel eingebaut, weil die Daten aus Tabelle [FactPlan] Budget-Daten sind, die nur Werte für das Jahr 2018 enthalten. Durch die Einschränkung der Tabelle [FactSales01] können die Aggregate aus den beiden Faktentabellen fachlich korrekt aufeinander abgebildet werden.

Measure bzw. Computed Column [SumPlannedAmount]

Der Wert für [SumPlannedAmount] wird mit Hilfe eines kaskadierenden Filters erreicht. [FactSales01] stellt das Start-Objekt für die Kaskade da. Mit "CALCULATETABLE ( FactSales01 ... " wird sicher gestellt, dass [FactSales01] als Start-Objekt selbst schon gefiltert ist: pro Produkt wird ein Filter auf der Tabelle [Product] erstellt und auf die Tabelle [FactSales01] übertragen. Die zusätzliche Einschränkung auf das Jahr 2018 hat den gleichen fachlichen Sinn wie oben.
Der Filter auf [FactSales01] wird nun schrittweise auf die nächsten Objekte in der Kaskade angewandt. Dies sind [Time] und [FactPlan].