Pokud použijeme v Power BI reportu vizuál Tabulka nebo vizuál Matice, může se v určitých situacích stát, že součet jednotlivých hodnot v řádcích nemusí vždy odpovídat hodnotě zobrazené v řádcích souhrnů. V takovýchto případech pracujeme s takzvaně neaditivním výpočty. Proč tomu tak je a jak případně udělat z neaditivního výpočtu výpočet aditivní si můžeme ukázat na jednoduchém příkladu.
Pozn.: K tomuto tématu je již k dispozici nový, aktualizovaný článek: Souhrn v Power BI vizuálu neodpovídá součtu hodnot v řádcích. Tento nový článek obsahuje více příkladů a také video návod.
Výpočet počtu jedinečných zákazníků v letech
V prvním kroku si vytvoříme měřítko, které bude vracet jedinečný počet zákazníků, kteří zakoupili jeden nebo více produktů.
Měřítko:
Toto měřítko bude vracet počet zákazníků v aktuálním kontextu vyhodnocení. Nové měřítko si můžeme vložit do vizuálu Tabulka, spolu s roky v řádcích.
Měřítko [Počet zákazníků] vrací v řádcích s jednotlivými roky počet zákazníků, kteří v daném roce zakoupili alespoň jeden produkt. V případě, že některý ze zákazníků nakupoval v daném roce vícekrát, je tento zákazník započítán pouze jednou.
Při pohledu na výše uvedený obrázek však uživatele reportu může zarazit, že jednotlivé hodnoty v řádcích s roky po sečtení neodpovídají součtu v posledním řádku tabulky, tedy v řádku souhrnů Total. To, že hodnota v řádku souhrnů neodpovídá součtu jednotlivých položek v řádcích ještě neznamená, že je výpočet špatně. Jako autoři bychom však měli být schopni správně interpretovat výsledky a v případě požadavku také vytvořit takový výpočet, ve kterém se bude součet jednotlivých položek v řádcích rovnat hodnotě v souhrnu.
Hodnoty v řádcích a hodnota v souhrnu
Pro pochopení neaditivních výpočtů, kde součet jednotlivých dílčích hodnot neodpovídá celku, musíme myslet na to, že každé měřítko je v každé buňce vizuálu vyhodnocena nezávisle na ostatních buňkách.
Měřítko použité ve vizuálu je vyhodnoceno v kontextu filtru roku v každém řádku zobrazené tabulky. V prvním řádku působí na měřítko filtr roku 2017. Pod tímto filtrem je vyhodnoceno měřítko [Počet zákazníků], které vrací počet jedinečných zákazníků z tabulky 'Sales' pro rok 2017. Obdobně pak výpočet probíhá i v dalších řádcích vizuálu pro všechny ostatní roky.
V řádku souhrnů již není aplikovaný na měřítko žádný filtr s roky. Měřítko je vyhodnoceno pro celou tabulku 'Sales'. Výsledné číslo v řádku souhrnů tedy vyjadřuje jedinečný počet zákazníků, kteří nakoupili nějaké zboží v kterémkoliv roce.
Součet jednotlivých hodnot v řádcích neodpovídá hodnotě v řádku souhrnů proto, že stejní zákazníci nakupují zboží opakovaně v různých letech. Pokud jeden zákazník nakupoval ve všech letech, v řádku souhrnů je započítán pouze jednou, zatímco v jednotlivých letech se může vyskytovat vícekrát. Hodnota v řádku souhrnů by odpovídala součtu hodnot v řádcích pouze v situaci, kdy by v každém roce nakupovali zboží jiní zákazníci. Pokud bychom chtěli v řádku souhrnů i přesto vidět součet jednotlivých hodnot za každý rok, musíme použít jiný typ výpočtu.
Jak získat součet jedinečných hodnot z řádků do souhrnu
Měřítko, které bude vracet součet jedinečných zákazníků za jednotlivé roky v řádku souhrnů může vypadat následovně.
Měřítko:
Měřítko [Počet zákazníků 2] si pro porovnání můžeme vložit do původního vizuálu.
Funkce SUMX() je iterační funkce, která pro každý řádek tabulky uvedené v prvním argumentu vyhodnotí výraz ve druhém argumentu funkce. Pokud probíhá výpočet v prvním řádku vizuálu tabulky, působí na tabulku VALUES('Date'[Rok]) v prvním argumentu funkce filtr roku 2017. Tento filtr umožní provést výpočet druhého argumentu pouze pro rok 2017. Stejný princip je pak aplikován pro řádky s ostatními roky.
V řádku souhrnů pak tabulka VALUES('Date'[Rok]) obsahuje všechny roky, protože na ni nepůsobí žádný vnější filtr, jako tomu bylo s řádky s roky. Druhý argument ve funkci SUMX() je tedy postupně vyhodnocen každý jednotlivý rok, a funkce SUMX() jedinečné hodnoty za každý rok následně sečte. Výsledek v řádku souhrnů pak odpovídá součtu hodnot v jednotlivých letech.
Ačkoliv se může zdát, že měřítko [Počet zákazníků 2] nyní vrací v řádku souhrnů správnou hodnotu, opak je pravdou. V tomto konkrétním příkladě jsme programově udělali z neaditivního měřítka [Počet zákazníků] aditivní měřítko [Počet zákazníků 2]. Tímto krokem ale v řádku souhrnů zobrazujeme více zákazníků, než ve skutečnosti máme, protože jsme některé zákazníky započítali v řádku souhrnů vícekrát. Vícekrát jsou v řádku souhrnů započítáni ti zákazníci, kteří nakupovali produkty ve více letech.
V některých typech výpočtů může dávat smysl upravit neaditivní výpočet na aditivní výše uvedeným způsobem, nicméně vždy si musíme být v těchto typech výpočtů jistí, co počítáme a jaký význam má hodnota měřítka v daném kontextu.
Změna kontextu řádku na kontext filtru
Důležitou roli ve výpočtu měřítka [Počet zákazníků 2] je funkce CALCULATE(), do které je zabalena funkce DISTINCTCOUNT(). Pro zopakování se můžeme ještě jednou podívat na definici měřítka [Počet zákazníků 2].
Měřítko:
Funkce SUMX() je iterační funkce, u které vzniká kontext řádku pro každý řádek tabulky uvedené jako první argument této funkce - výraz VALUES('Date'[Rok]). Druhý argument ve funkci SUMX() je vyhodnocen v kontextu každého řádku této tabulky, nicméně funkce DISTINCTCOUNT() kontext řádku ignoruje. Pokud bychom tedy nepoužili funkci CALCULATE(), tak by funkce DISTINCTCOUNT() vracela při výpočtu v řádku souhrnu v každém kroku iterace počet jedinečných hodnot za všechny roky, a ty by pak v rámci funkce SUMX() sčítala. Výsledek bez použití funkce CALCULATE() by představoval počet jedinečných zákazníků za všechny roky násobený počtem roků.
Funkce CALCULATE() ale změní kontext řádku na kontext filtru, a funkce DISTICNTCOUNT() je vyhodnocena v rámci iterace v kontextu filtru každého roku.
Cílem této krátké ukázky bylo vysvětlit, proč v některých typech výpočtů v jazyku DAX neodpovídá součet jednotlivých hodnot v řádcích hodnotě zobrazené v řádku souhrnů. Těmto výpočtům se říká neaditivní a jde o výpočty, ve kterých součet dílčích hodnot neodpovídá celku. Pomocí jazyka DAX můžeme relativně jednoduše vytvořit z neaditivního výpočtu výpočet aditivní použitím některé z iteračních funkcí, jako je například funkce SUMX() použitá v příkladu v tomto příspěvku. Vytvořit z neaditivního výpočtu aditivní ovšem dává smysl pouze pro některé specifické typy výpočtů a příklad s počtem jedinečných zákazníků mezi ně nepatří.
Pokud tedy narazíme na problém, kdy hodnota v souhrnu neodpovídá součtu dílčích hodnot v řádcích, je třeba se zamyslet nad významem jednotlivých hodnot v každém řádku vizuálu a rozhodnout, zda má být použité měřítko v aktuálním kontextu aditivní - má smysl sčítat dílčí hodnoty, nebo neaditivní - nemá smysl sčítat dílčí hodnoty. Pokud je daný výpočet neaditivní, je vždy lepší raději vysvětlit uživatelům reportu význam hodnoty v řádku souhrnů než zobrazovat špatné výsledky.
Komentáře
Okomentovat