Kapitola 3
Úvod do jazyka DAX
Naučte se základy DAX—syntax, datové typy a nejčastěji používané funkce
Co se naučíte
- Pochopit všechny datové typy v DAX a jak s nimi zachází
- Conversions: Implicitní vs explicitní (VALUE, INT, CONVERT)
- Chování BLANK v aritmetice a agregacích
- Syntaxi DAX, funkce, komentáře
- Agregační funkce: SUM, AVERAGE, COUNT, DISTINCTCOUNT
- Logické, textové a datumové funkce
3.1
Datové typy v DAX
DAX podporuje sedm hlavních datových typů, které ovlivňují, jak se data ukládají, filtrují a agregují.
| Typ | Příklady | Poznámka |
|---|---|---|
| Integer | 42, -1, 0 | Celé číslo bez zlomku. Nejmenší paměť. |
| Decimal | 3.14159, 100.001 | Číslo s des. místy (IEEE 754 double precision — stejná přesnost jako Double). |
| Currency | $1234.56, €99.99 | Speciální typ pro peníze. Automaticky formátuje. |
| DateTime | 2023-08-15 14:30:00 | Datum a čas. Interně floating-point (celá část = dny od 30.12.1899, stejně jako Excel). |
| Boolean | TRUE(), FALSE() | Logická hodnota. Používá se v IF a FILTER. |
| String | "Hello", "2023-01" | Text. Porovnávání hodnot je case-insensitive ("czech" = "Czech" → TRUE). Case-sensitive jsou pouze názvy objektů v kódu. |
| BLANK | BLANK(), NULL z SQL | Chybí hodnota. Speciální chování v agregacích. |
Pro počítače: DAX interně používá IEEE 64-bit double precision pro čísla. Decimal typ také.
3.2
Konverze datových typů
Implicitní konverze (Automatická)
DAX se někdy automaticky snaží převést typ. Např. "123" + 1 vede na 124.
DAX
-- Implicitní konverze: String → Number "100" + 50 -- Vrací 150 (implicitní konverze textu na číslo) -- Ale pro bezpečnost, používejte explicitní konverzi VALUE("100") + 50 -- Lépe: vrací 150
Explicitní konverze (Zajištěnější)
| Funkce | Popis | Příklad |
|---|---|---|
| VALUE() | String → Number | VALUE("123.45") → 123.45 |
| INT() | Number → Integer (zaokrouhlí dolů) | INT(3.7) → 3 |
| CONVERT() | Jakýkoli typ → jakýkoli typ | CONVERT("2023-01-15", DateTime) |
| TEXT() | Cokoliv → String | TEXT(123, "0.00") → "123.00" |
Pozor na chyby: VALUE("abc") vrací chybu. Vždy validujte vstupní data nebo použijte IFERROR.
3.3
BLANK() hodnoty a jejich chování
BLANK je DAX reprezentace "žádné hodnoty". Na rozdíl od SQL NULL se BLANK v aritmetice chová jako 0 — nevzniká "nakažení" jako u NULL. Míra vracející 0 zobrazí 0; prázdnou buňku zobrazí pouze míra vracející BLANK().
| Operace | Výsledek | Vysvětlení |
|---|---|---|
| BLANK() + 10 | 10 | BLANK se chová jako 0; výsledek je 10 |
| BLANK() * 10 | 0 | BLANK jako 0; výsledek je 0 — zobrazí se jako 0 (ne prázdno) |
| BLANK() / 10 | 0 | BLANK jako 0; výsledek je 0 — zobrazí se jako 0 (ne prázdno) |
| BLANK & "text" | "text" | Concatenation: BLANK se ignoruje |
| SUM(..., BLANK) | Ignoruje BLANK | Agregace: BLANK se vynechávají |
Práce s BLANK
DAX
-- Detekce BLANK ISBLANK(SomeColumn) -- TRUE pokud BLANK -- Nahrazení BLANK výchozí hodnotou COALESCE(Value, 0) -- Vrací Value nebo 0 pokud BLANK -- Podmínění na BLANK IF(ISBLANK(Email), "No email", Email)
COALESCE vs IF(ISBLANK): COALESCE je čitelnější a efektivnější. Vrací první nenulovou hodnotu z seznamu.
3.4
Syntaxe DAX: Funkce, operátory, komentáře
Základní struktura
DAX
-- Komentář jednoduché čáry (jakýkoli text) MEASURE Prodeje[Prodej celkem] = SUM(Prodeje[Částka]) -- Measure: výraz, který se vyhodnocuje v kontextu filtru COLUMN Prodeje[Bonus] = Prodeje[Částka] * 0.1 -- Počítaný sloupec: vyhodnocuje se řádek po řádku
Operátory
| Operátor | Popis | Příklad |
|---|---|---|
| +, -, *, / | Aritmetika | 10 + 5 = 15 |
| & | Concatenation (String) | "Hello" & " World" |
| = | Equals (porovnání) | Status = "Active" |
| <, >, =, <> | Srovnání | Věk > 18 |
Funkce a konvence
DAX identifikátory (názvy tabulek i sloupců) jsou case-insensitive — Sales[Amount] a Sales[amount] odkazují na stejný sloupec. Funkce jsou rovněž case-insensitive (SUM = sum).
DAX
-- Správná syntax CALCULATE( SUM(Sales[Amount]), Date[Year] = 2023 ) -- Také funkční — DAX identifikátory jsou case-insensitive SUM(Sales[amount]) -- Totéž co Sales[Amount]
3.5
Agregační funkce
Agregační funkce kombinují více řádků do jedné hodnoty. Jsou výchozím chováním měr.
| Funkce | Popis | Příklad |
|---|---|---|
| SUM() | Součet všech čísel | SUM(Sales[Amount]) |
| AVERAGE() | Průměr | AVERAGE(Sales[Amount]) |
| MIN(), MAX() | Minimum, Maximum | MIN(Sales[Amount]) |
| COUNT() | Počet buněk (bez BLANK) | COUNT(Sales[Amount]) |
| COUNTA() | Počet neprázdných buněk | COUNTA(Sales[ProductName]) |
| COUNTROWS() | Počet řádků tabulky | COUNTROWS(Sales) |
| DISTINCTCOUNT() | Počet jedinečných hodnot | DISTINCTCOUNT(Sales[ProductKey]) |
DAX
-- Reálné příklady z modelu AdventureWorks DW 2019 # Internet = SUM(FactInternetSales[SalesAmount]) # Reseller = SUM(FactResellerSales[SalesAmount]) -- AVERAGE: průměrná prodejní cena na objednávce # Prumer Internet = AVERAGE(FactInternetSales[SalesAmount]) -- DISTINCTCOUNT: počet unikátních zákazníků # Zakaznici = DISTINCTCOUNT(FactInternetSales[CustomerKey])
Proč dvě základní míry? Protože AdventureWorks má dva prodejní kanály — Internet (přímé online prodeje) a Reseller (prodej přes distributory). Každý kanál má svou fact tabulku a své míry.
3.6
Logické funkce
| Funkce | Popis | Příklad |
|---|---|---|
| IF() | Podmíněný výraz | IF(Age >= 18, "Adult", "Minor") |
| AND() | Logické AND | AND(Status = "Active", Age > 18) |
| OR() | Logické OR | OR(Country = "CZ", Country = "SK") |
| NOT() | Negace | NOT(ISBLANK(Email)) |
| SWITCH() | Vícevodá rozhodnutí | SWITCH(Level, 1, "Bronze", 2, "Silver") |
| IFERROR() | Zachyti chybu | IFERROR(VALUE(Text), 0) |
DAX
-- IF + AND pro kategorizaci IF( AND(Revenue > 100000, Status = "Active"), "High Value", "Standard" ) -- SWITCH pro ranking SWITCH( INT(Score / 20), 5, "A", 4, "B", 3, "C", "F" )
3.7
Textové funkce
| Funkce | Popis | Příklad |
|---|---|---|
| & | Concatenation | "Hello" & " " & "World" |
| & operátor | Concatenation (doporučeno; CONCATENATE() má přesně 2 argumenty) | FirstName & " " & LastName -- CONCATENATE() má jen 2 argumenty |
| FORMAT() | Formátuj číslo/datum | FORMAT(1234.5, "#,##0.00") |
| LEFT(), RIGHT() | Prvních/posledních N znaků | LEFT("Hello", 2) → "He" |
| MID() | Podřetězec | MID("Hello", 2, 3) → "ell" |
| LEN() | Délka řetězce | LEN("Hello") → 5 |
| UPPER(), LOWER() | Velká/malá písmena | UPPER("hello") → "HELLO" |
| TRIM() | Odstraň mezery | TRIM(" hello ") → "hello" |
3.8
Datumové funkce
| Funkce | Popis | Příklad |
|---|---|---|
| DATE() | Vytvoř datum z roku, měsíce, dne | DATE(2023, 8, 15) |
| TODAY() | Dnešní datum | TODAY() → 2023-08-15 |
| NOW() | Aktuální čas a datum | NOW() → 2023-08-15 14:30:00 |
| YEAR(), MONTH(), DAY() | Extrahuj část data | YEAR([OrderDate]) → 2023 |
| WEEKDAY() | Den týdne (1-7) | WEEKDAY([Date], 2) → 3 (středa) |
| EDATE() | Datum + N měsíců | EDATE([Date], 3) → o 3 měsíce později |
DAX
-- Formátování data s textem FORMAT([OrderDate], "dddd, dd.mm.yyyy") -- Výsledek: "Monday, 15.08.2023" -- Výpočet věku INT((TODAY() - [BirthDate]) / 365.25)