Porovnání textových řetězců v jazyku DAX

Porovnání textových řetězců v jazyku DAX

Tento příspěvek obsahuje vybrané příklady porovnání textových řetězců s použitím DAX funkcí v Power BI. V článku se například můžete dozvědět, jak ověřit výskyt části textu v textovém řetězci, jaké funkce jsou při práci s textem citlivé na velká a malá písmena (case sensitive) nebo jak ověřit, zda textový řetězec obsahuje více slov definovaných v podmínce.

Všechny příklady v tomto příspěvku jsou vytvořeny ve cvičném Power BI souboru Adventure Works DW 2020.pbix, který je volně dostupný ke stažení na internetu. Soubor s řešením je k dispozici ke stažení níže pod tímto příspěvkem.

Příklady prohledání textových řetězců v jazyku DAX

Ve všech příkladech uvedených v tomto příspěvku budeme pro zjednodušení pracovat s jedním sloupcem, a to se sloupcem 'Product'[Model], který obsahuje názvy jednotlivých modelů.

Porovnání textových řetězců v jazyku DAX 2

Abychom si mohli v Power BI vizuálech snadno zobrazovat výsledky příkladů, vytvoříme si pomocné měřítko, které bude jednoduše načítat text z aktuálního řádku vizuálu na obrázku výše. Tento text pak budeme v příkladech různým způsobem prohledávat a porovnávat. Pomocné měřítko, které načítá text z aktuálního řádku vizuálu vypadá následovně.

Měřítko:

Vybraný model = SELECTEDVALUE('Product'[Model])

Výsledkem tohoto měřítka není nic jiného než text s názvem aktuálního modelu.

Porovnání textových řetězců v jazyku DAX 3

V příkladech se tedy budeme při práci s textem odkazovat na měřítko [Vybraný model]. Pokud bychom některý z příkladů uvedených v následující části chtěli aplikovat například jako filtr ve funkci CALCULATE(), jako filtrovací podmínku ve funkci FILTER() nebo v definici nového počítaného sloupce, stačí pomocné měřítko [Vybraný model] nahradit odkazem na sloupec s textovými hodnotami určenými pro porovnání.

Jak zjistit zda textový řetězec obsahuje jiný text v jazyku DAX

Zjistit zda textový řetězec obsahuje hledané části textu můžeme v jazyku DAX pomocí čtyř funkcí - CONTAINSSTRING(), CONTAINSSTRINGEXACT(), SEARCH() a FIND().  Funkce CONTAINSSTRING() a CONTAINSSTRINGEXACT() jsou novější funkce a v případě že jsou podporované používanou verzí Tabulárního modelu, měli bychom upřednostnit k prohledání textových řetězců výhradně tyto dvě funkce.

Alternativně ve starších verzích Tabulárního modelu, například v Power Pivot v Excelu, můžeme použít funkce SEARCH() a FIND(), nicméně tyto funkce vyžadují další dodatečnou logiku, protože nevrací přímo hodnoty TRUE/FALSE, ale vrací pozici počátečního znaku hledaného textu.

Funkce CONTAINSSTRING() a SEARCH() nerozlišují malá a velká písmena (case insensitive). Funkce CONTAINSSTRINGEXACT() a FIND() rozlišují velká a malá písmena (case sensitive).

Zjistit zda prohledávaný textový řetězec obsahuje jiný text můžeme pomocí funkce CONTAINSSTRING() následujícím způsobem.

Měřítko:

Obsahuje (nerozlišuje malá/velká písmena) =
    CONTAINSSTRING([Vybraný model], "pump")

Prvním argumentem funkce CONTAINSSTRING() je prohledávaný textový řetězec. Druhým argumentem je hledaný text. Alternativně při nedostupnosti funkce CONTAINSSTRING() můžeme použít následující ekvivalentní výraz s použitím funkce SEARCH(), 

Měřítko:

Obsahuje alternativní (nerozlišuje malá/velká písmena) =
    SEARCH("pump", [Vybraný model], 1, 0) > 0

Prvním argumentem funkce SEARCH() je hledaný text. Druhým argumentem je prohledávaný text. Třetím argumentem je počáteční pozice pro prohledávání v prohledávaném textu, kde zadáváme číslo jedna v případě že chceme prohledat celý text od prvního znaku. Čtvrtý argument je alternativní výsledek v případě chyby. Funkce SEARCH() vrací v případě nalezení hledaného textu počáteční pozici tohoto textu v prohledávaném textovém řetězci. Proto ještě výsledek této funkce musíme použít v logickém výrazu, kde jednoduše porovnáváme zda je výsledná hodnota funkce SEARCH() větší než nula. 

Pokud obě nová měřítka vložíme do vizuálu Tabulka s jednotlivými modely v řádcích, výsledek bude vypadat následovně.

Porovnání textových řetězců v jazyku DAX 4

Jak je vidět na obrázku výše, obě měřítka vrací hodnotu TRUE v případě, že text ve sloupci 'Product'[Model] obsahuje hledaný text "pump", bez ohledu na malá a velká písmena. Pokud bychom chtěli prohledávat text s ohledem na malá a velká písmena, můžeme funkci CONTAINSSTRING() nahradit funkcí CONTAINSSTRINGEXACT() následujícím způsobem.

Měřítko:

Obsahuje (rozlišuje malá/velká písmena) =
    CONTAINSSTRINGEXACT([Vybraný model], "pump")

V případě použití alternativního přístupu s funkcí SEARCH() nahradíme tuto funkci funkcí FIND(), která rozlišuje malá a velká písmena.

Měřítko:

Obsahuje alternativní (rozlišuje malá/velká písmena) =
    FIND("pump", [Vybraný model], 1, 0) > 0

Výsledek pak bude vypadat následovně.

Porovnání textových řetězců v jazyku DAX 5

Textový řetězec můžeme testovat také na výskyt více textů, které mohou být v textovém řetězci na kterémkoliv místě za sebou. Pokud bychom například chtěli vyhledat model, který obsahuje slova "road" a "wheel", můžeme použít následující výraz, kde je mezi jednotlivými slovy vložen znak hvězdičky.

Měřítko:

Obsahuje více slov (nerozlišuje malá/velká písmena) =
    CONTAINSSTRING([Vybraný model], "road*wheel")

V případě nedostupnosti funkce CONTAINSSTRING() můžeme použít alternativní přístup s funkcí SEARCH() následujícím způsobem.

Měřítko:

Obsahuje více slov alternativní (nerozlišuje malá/velká písmena) =
    SEARCH("road*wheel", [Vybraný model], 1, 0) > 0

Výsledkem obou měřítek bude hodnota TRUE v případě že zadaný textový řetězec, tedy název modelu, obsahuje slova "road" a "wheel", bez ohledu na malá a velká písmena. V tomto případě si ovšem musíme dát pozor na pořadí, v jakém jsou hledaná slova oddělená hvězdičkou zadána. Výše uvedená měřítka budou vracet hodnotu TRUE pouze v případě, že v textovém řetězci bude slovo "road" před slovem "wheel".

Porovnání textových řetězců v jazyku DAX 6

Pokud je v prohledávaném textovém řetězci hledaný text vždy na začátku nebo na konci, měli bychom z důvodu lepšího výkonu při vyhledávání použít funkce LEFT() nebo funkci RIGHT().

Hledaný text na začátku nebo na konci textového řetězce

Pro zjištění zda je v textovém řetězci hledaný text na začátku použijeme funkci LEFT() následujícím způsobem.

Měřítko:

Začíná na (nerozlišuje malá/velká písmena) =
    LEFT([Vybraný model], 4) = "road"

Výsledkem výrazu bude hodnota TRUE v případě, že první čtyři znaky v prohledávaném textu odpovídají textu "road", bez ohledu na malá a velká písmena.

Porovnání textových řetězců v jazyku DAX 7

Obdobným způsobem můžeme použít funkci RIGHT() pro ověření, zda se hledaný text nachází na konci prohledávaného textového řetězce.

Měřítko:

Končí na (nerozlišuje malá/velká písmena) =
    RIGHT([Vybraný model], 5) = "wheel"

Výsledkem výše uvedeného výrazu bude hodnota TRUE v případě, kdy prohledávaný text obsahuje slovo "wheel" na konci textového řetězce, bez ohledu na malá a velká písmena.

Porovnání textových řetězců v jazyku DAX 8

Všechny výše uvedené příklady můžeme také kombinovat, například vložením jednotlivých podmínek do funkce AND() nebo OR().

Kombinace více podmínek při prohledávání textových řetězců

Pro kombinaci více podmínek můžeme použít funkce AND() nebo OR(), nebo alternativně operátory && (AND) a || (OR). Pokud bychom například chtěli zjistit, zda prohledávaný text obsahuje na začátku slovo "road" a současně na kterémkoliv místě řetězec "550", můžeme použít následující výraz.

Měřítko:

Začíná na a obsahuje (nerozlišuje malá/velká písmena) =
AND
(
    LEFT([Vybraný model], 4) = "road",
    CONTAINSSTRING([Vybraný model], "550")
)

Jak je možné vidět na obrázku níže, výše uvedeným podmínkám odpovídá pouze jeden model.

Porovnání textových řetězců v jazyku DAX 9

Další měřítko pak bude vracet hodnotu TRUE pro modely, které obsahují na konci slovo "wheel" a kdekoliv slovo "road", bez ohledu na malá a velká písmena.

Měřítko:

Končí na a obsahuje (nerozlišuje malá/velká písmena) =
AND
(
    RIGHT([Vybraný model], 5) = "wheel",
    CONTAINSSTRING([Vybraný model], "road")
)

Výsledek výše uvedeného výpočtu můžeme vidět na následujícím obrázku.

Porovnání textových řetězců v jazyku DAX 10

Jak již bylo uvedeno na začátku tohoto příspěvku, cílem výše uvedených příkladů je pouze znázornit různé možnosti prohledávání textových řetězců. Jako textový řetězec jsme pro zjednodušení používali měřítko [Vybraný model]. 

V reálných výpočtech se obvykle nepoužívají pro prohledávání měřítka která obsahují text, ale prohledávají se přímo sloupce s textovými řetězci, které pak mohou sloužit jako filtry ve filtrovacích funkcích, jako jsou funkce FILTER(), CALCULATE() nebo CALCULATETABLE().

Příklad použití textových funkcí ve filtru funkce CALCULATE

V jednom z předchozích příkladů jsme si ukazovali jak ověřit, zda je v prohledávaném textu na začátku slovo "road" a současně zda tento text obsahuje číslo "550".

 Měřítko:

Začíná "road" a obsahuje "550" =
AND
(
    LEFT([Vybraný model], 4) = "road",
    CONTAINSSTRING([Vybraný model], "550")
)

Pokud toto měřítko vložíme do vizuálu Tabulka s názvy modelů v řádcích a přidáme také měřítko [Prodeje], můžeme vidět že model, který splňuje podmínky definované v měřítku [Začíná "road" a obsahuje "550"], má celkové tržby ve výši 5 183 006,24.

Porovnání textových řetězců v jazyku DAX 11

Pokud bychom chtěli podmínku "road" na začátku a "550" kdekoliv aplikovat přímo v měřítku jako filtr ve funkci CALCULATE(), můžeme použít následující definici měřítka, kde ve filtru funkce CALCULATE() nahradíme pomocné měřítko [Vybraný model] sloupcem 'Product'[Model].

Měřítko:

Prodeje (začíná "road" a obsahuje "550") =
CALCULATE
(
    [Prodeje],
    AND
    (
        LEFT('Product'[Model], 4) = "road",
        CONTAINSSTRING('Product'[Model], "550")
    )
)

Výsledkem měřítka [Prodeje (začíná "road" a obsahuje "550")] bude suma za prodeje pouze těch modelů, které splňují definovanou podmínku, což je opět částka 5 183 006,24.

Porovnání textových řetězců v jazyku DAX 12

Obdobně bychom mohli použít podmínku definovanou v měřítku [Prodeje (začíná "road" a obsahuje "550")] například ve funkci FILTER() nebo ve funkci CALCULATETABLE(). 

V případě problémů s výkonem takto definovaných měřítek je možné uložit si logickou podmínku v počítaném sloupci, a následně filtrovat v měřítku pouze tento pomocný sloupec s hodnotami TRUE/FALSE.

Další příklady můžete najít na stránce DAX příklady nebo na stránce Power BI.

Komentáře