Jak fungují agregační funkce v jazyku DAX

Úvodní obrázek

Jazyk DAX obsahuje celou řadu agregačních funkcí, jejichž použití je samo o sobě velmi intuitivní. Nicméně v některých složitějších vzorcích, kdy pracujeme s jednou nebo vnořenými iteračními funkcemi, může být výsledek jiný, než autor očekává. Proto je dobré znát, jak agregační funkce fungují a na co si dát pozor.

Jak fungují agregační funkce

Mezi běžně používané agregační funkce patří funkce SUM()COUNT()MAX()MIN() a nebo AVERAGE(). Agregačních funkcí je ale více, řadíme mezi ně také funkce DISTINCTCOUNT() nebo COUNTROWS(). Kompletní výčet agregačních funkcí je dostupný v oficiální dokumentaci.

Pozn.: V jazyku DAX jsou k dispozici dva typy sumarizačních funkcí. Například sumu hodnot z jednoho sloupce můžeme získat pomocí funkce SUM(), stejně tak jako pomocí pokročilejší funkce SUMX(). Rozdíl mezi funkcí SUM() a funkcí SUMX() je popsán v samostatném příspěku. V tomto příspěvku budeme pro zjednodušení pracovat pouze s funkcí SUM().

Agregační funkce v kontextu řádku

Agregační funkce při vyhodnocení ignorují kontext řádku, který je vyvolán při vytvoření nového počítaného sloupce v tabulce nebo v iteračních funkcích. Tato vlastnost umožňuje vytvořit agregaci hodnot nad sloupcem uvedeným v argumentu funkce. Tuto vlastnost si můžeme znázornit právě na příkladu vytvoření počítaného sloupce. Ve cvičném souboru Adventure Works DW 2020.pbix si můžeme vytvořit nový počítaný sloupec v tabulce 'Sales', se sumou hodnot ze sloupce 'Sales'[Sales Amount].

Počítaný sloupec:

Suma prodejů = SUM(Sales[Sales Amount])

Nový počítaný sloupec se sumou hodnot za prodané produkty se stane součástí tabulky 'Sales'.

Jak fungují agregační funkce v jazyku DAX

Při vytvoření nového počítaného sloupce vzniká kontext řádku. Jak je možné vidět na obrázku výše, výsledek nového počítaného sloupce je v každém řádku stejný, a představuje sumu všech hodnot ze všech řádku ze sloupce 'Sales'[Sales Amount].  Při výpočtu vzniká v každém řádku tabulky kontext řádku, nicméně sumarizační funkce kontext řádku ignorují, proto je výsledkem stejná hodnota v každém řádku tabulky. 

Agregační funkce v kontextu filtru

Stejný vzorec, který jsme použili pro vytvoření počítaného sloupce, můžeme použít také pro vytvoření měřítka.

Měřítko:

Suma prodejů (Měřítko) = SUM(Sales[Sales Amount])

Nové měřítko můžeme vložit do vizuálu tabulky spolu s hodnotami ze sloupce 'Sales'[SalesOrderLineKey]. Tento sloupce je jedinečný identifikátor v tabulce 'Sales'. Na obrázku níže pak můžeme vidět, že hodnoty nově vytvořeného měřítka [Suma prodejů (Měřítko)] jsou jiné, než v případě stejného výpočtu v počítaném sloupci.

Jak fungují agregační funkce v jazyku DAX 2

Měřítko [Suma prodejů (Měřítko)] je vyhodnoceno v kontextu filtru každého řádku zobrazené tabulky. Měřítko je vyhodnoceno v každé buňce samostatně, v kontextu filtru hodnoty v prvním sloupci vizuálu. Pokud tedy použijeme kterékoliv měřítko v jakémkoliv vizuálu v Power BI, pak řádky v tabulce tvoří kontext filtru, stejně jako případné jiné vizuály, včetně grafů, průřezů atd. Jelikož je v řádcích vizuálu na obrázku výše v prvním sloupci primární klíč z tabulky 'Sales', hodnoty měřítka [Suma prodejů (Měřítko)] odpovídají v každém řádku vizuálu hodnotám ze sloupce 'Sales'[Sales Amount]. V řádku souhrnů již na měřítko nepůsobí žádný filtr, a hodnota v řádku souhrnů odpovídá sumě hodnot ze sloupce 'Sales'[Sales Amount] ze všech řádků tabulky 'Sales'.

Pokud měřítko [Suma prodejů měřítko] použijeme v tabulce s kategoriemi produktů v řádcích, výsledek bude vypadat následovně.

Jak fungují agregační funkce v jazyku DAX 3

Měřítko [Suma prodejů (Měřítko)] je nyní vyhodnoceno v každém řádku vizuálu v kontextu filtru každé kategorie. V prvním řádku tabulky tak hodnota měřítka odpovídá celkovým prodejům produktů z kategorie "Accessoies". V řádku souhrnů pak hodnota odpovídá celkovým prodejům za všechny produkty, bez ohledu na kategorii.

Kontext řádku v iteračních funkcích

Kontext řádku vzniká také při vyhodnocení výrazů v iteračních funkcích. Pokud bychom například chtěli vytvořit novou počítanou tabulku, kde budou v jednom sloupci kategorie, a ve druhém sloupci suma celkových prodejů za každou kategorii, následující přístup nebude fungovat.

Počítaná tabulka:

Kategorie a prodeje =
ADDCOLUMNS
(
VALUES('Product'[Category]),
"Prodeje v kategorii",
SUM(Sales[Sales Amount])
)

Výsledná tabulka obsahuje dva sloupce. První sloupec s názvem kategorií produktů, druhý sloupec se sumou celkových prodejů za všechny produkty, bez ohledu na kategorii.

Jak fungují agregační funkce v jazyku DAX 4

Funkce ADDCOLUMNS() je iterační funkce, která tvoří pro každý řádek tabulky v prvním argumentu funkce kontext řádku. Výraz SUM(Sales[Sales Amount]) v šestém řádku kódu na obrázku výše je  vyhodnocen v kontextu řádku každé kategorie. Výsledkem je pro každou kategorii stejná hodnota, která představuje sumu celkových nákladů ze všech řádků tabulky 'Sales', bez ohledu na kategorii. Důvod je opět stejný, a to že agregační funkce SUM(), stejně jako ostatní agregační funkce, ignoruje nově vytvoření kontext řádku, který vzniká ve funkci funkci ADDCOLUMNS(). Pokud chceme ve sloupci 'Kategorie a prodeje'[Prodeje v kategorii]  pouze hodnoty vztahující se ke konkrétní kategorii, můžeme použít funkci CALCULATE(), která změní kontext řádku na kontext filtru.

Počítaná tabulka:

Kategorie a prodeje =
ADDCOLUMNS
(
VALUES('Product'[Category]),
"Prodeje v kategorii",
CALCULATE
(
SUM(Sales[Sales Amount])
)
)

Výsledek pak bude vypadat následovně.

Jak fungují agregační funkce v jazyku DAX 5

Nyní již  hodnoty ve sloupci 'Kategorie a prodeje'[Prodeje v kategorii]  odpovídají v každém řádku tabulky celkovým prodejům v každé kategorii. Funkce CALCULATE(), do které jsme vložili funkci SUM(), změnila existující kontext řádku na kontext filtru, ve kterém je nově sumarizační funkce vyhodnocena. Změna kontextu řádku na kontext filtru může v některých situacích vyvolat neočekávané výsledky. Více o informací o změně kontextu řádku na kontext filtru můžete najít v samostatném příspěvku.

Shrnutí

Agregační funkce ignorují kontext řádku. Kontext řádku vzniká při vytváření nového kalkulovaného sloupce nebo v iteračních funkcích. Pokud chceme změnit kontext řádku na kontext filtru a známe princip změny kontextu se všemi jeho důsledky, můžeme pro tento účel v některých situacích použít funkci CALCULATE(). Sumarizační funkce použité v definici měřítek jsou pak vyhodnoceny v reportech v takzvaném kontextu vyhodnocení. Kontext vyhodnocení může obsahovat jak kontext řádku, tak kontext filtru. Kontext filtru může vznikat v reportech například v řádcích vizuálu tabulky, v grafech nebo v průřezech. Kontext filtru a kontext řádku jsou základní koncepty, které je dobré znát při práci s daty v Power BI. Více příkladů, včetně základních informací o kontextu řádku a kontextu filtru, můžete najít na stránce DAX - Průvodce.

č. 12

Komentáře