Split in DAX

Es kommt ja ab und zu vor, dass man einen String nach einem Trennzeichen splitten will und dann aus einer Zeile mehrere Zeilen machen will.

Problem: Einen String Splitten

Beispielsweise möchte man aus dem String

A|B|C|D

die Tabelle

A
B
C
D

machen.

EVALUATE
VAR txt = "A|B|C|D"
RETURN
    ADDCOLUMNS (
        GENERATESERIES ( 1, PATHLENGTH ( txt ) ),
        "Spalte", PATHITEM ( txt, [Value], TEXT )
    )

liefert

Spalte mit Value 1-4 und A-D als separate Zeilen

Das ist also die Lösung des Problems. Natürlich kann man noch die Value-Spalte löschen, z.B. mit SELECTCOLUMNS.

Wir haben uns hier folgendes zu nutze gemacht:

  • Wenn man als Trenner | verwendet, kann man die eingebauten Funktionen PATHITEM, PATHLENGTH verwenden
  • Wenn man einen anderen Trenner verwendet, kann man ggf. den Trenner durch | ersetzen
  • GENERATESERIES erzeugt eine einspaltige Tabelle (Spalte heißt Value) mit Zahlen von 1 bis n

Für Fortgeschrittene: Einen String in einer Tabelle splitten

Im obigen Beispiel haben wir einen Text gesplittet. Nun kann es aber sein, dass man in einer Tabelle eine Spalte hat, die man splitten will und dann entsprechend mehr Zeilen bekommen will.

Also z.B. aus der Tabelle

KeyText
DavidA|B
PeterC|D|E|F

möchte man die Tabelle

KeyZelle
DavidA
DavidB
PeterC
PeterD
PeterE
PeterF

machen.

Im SQL würde man dazu CROSS APPLY verwenden.

In DAX geht es wie folgt:

EVALUATE
VAR tabelle =
    UNION (
        ROW ( "Key", "David", "Text", "A|B" ),
        ROW ( "Key", "Peter", "Text", "C|D|E|F" )
    )
RETURN
    SELECTCOLUMNS (
        ADDCOLUMNS (
            GENERATE ( tabelle, GENERATESERIES ( 1, PATHLENGTH ( [Text] ) ) ),
            "Spalte", PATHITEM ( [Text], [Value], TEXT )
        ),
        "Key", [Key],
        "Zelle", [Spalte]
    )

Gehen wir die einzelnen Schritte durch:

Zunächst erstelle ich die Ausgangstabelle wie oben. Dies steht dann in der Variable tabelle:

Ausgangstabelle

Das GENERATE führt dann für jede Zeile die GENERATESERIES – Funktion aus. Dort steht der jeweilige Text aus der Zeile. Die PATHLENGTH ist also für die erste Zeile 2, für die zweite 4. Das Ergebnis vom GENERATE ist somit:

Über das Addcolumns holen wir uns die jeweilige Stelle aus dem zu splittenden String:

Und das Ergebnis des gesamten DAX Statements ist:

Also genau das, was wir zeigen wollten 🙂

DMVs angewandt: Finde Berechnungen im Cube mit einer bestimmten Zeichenkette

In 2018 hatte ich schon mal was über DMVs (Data Management Views) geschrieben – damals noch über die aus der MOLAP-Welt. Es gibt sie natürlich auch für tabulare Modelle (s. Link oben).

Über die DMVs kann man sich z.B. ausgeben lassen,

  • wann Partitionen zuletzt verarbeitet wurden
  • in welchen Ordnern welche Kennzahlen liegen
  • welche Tabellen es gibt
  • mit welchen Formeln berechnete Spalten oder Measures berechnet werden

Dazu führt man die entsprechende DMV (Syntax s. obigen Link) einfach im SQL Server Management Studio in einer neuen Query aus. Die Query kann auch eine DAX-Query sein, auch wenn es natürlich kein DAX ist, was wir hier ausführen.

Ich hatte nun einmal die Aufgabenstellung alle Measures zu finden, die einen bestimmten String (z.B. einen Measurenamen) enthalten. Leider unterstützt die DMV-Sprache kein LIKE 🙁

Aber es wird die INSTR-Funktion unterstützt. Sucht man z.B. alle Measures, die „Mapping Fachabt“ enthalten, feuert man folgende Abfrage ab:

SELECT * FROM $System.TMSCHEMA_MEASURES
WHERE INSTR([Expression], 'Mapping Fachabt', 1)>1

Noch ein Hinweis: Wenn man nach einem einfachen Anführungszeichen sucht (was ja in der obigen Syntax als Indikator für eine Zeichenkette fungiert), muss man es verdoppeln. Wenn man nach „Filter(All(“ plus einem einfachen Anführungszeichen am Ende suchen will, kann man das mit folgender Abfrage machen:

SELECT * FROM $System.TMSCHEMA_MEASURES
WHERE INSTR([Expression], 'Filter(All(''', 1)>1