Radkontext och filterkontext i en Lucky Templates DAX-kod

I den här handledningen ska vi ta en titt på en bit DAX-kod. Du kanske redan har använt något sådant här. Eller så kanske du stöter på det och blir förvirrad över hur den här koden fungerar och hur både radkontext och filterkontext verkar interagera med varandra i bara en enda DAX-kod. Hur som helst kommer den här handledningen att titta på allt ovan i detalj. Du kan se hela videon av denna handledning längst ner på den här bloggen.

Först ska vi titta på själva koden. Sedan ska vi gå igenom teoridelen för att förstå den bättre. Slutligen kommer vi att titta på allt bakom kulisserna genom att använda.

Datamodellen som vi ska använda är i grunden en enkel försäljningsdatamodell som innehåller datum, försäljning och tabellen Produkter. Försäljningstabellen innehåller transaktioner för varje given dag. Tabellen Produkter innehåller information om försäljningsinformationen om produkterna varje given dag. Tabellen Datum innehåller endast ett fåtal kolumner för denna handledning.

Radkontext och filterkontext i en Lucky Templates DAX-kod

Vi är bara intresserade av tabellen Datum, men vi kommer att använda tabellen Försäljning och tabellen Produkter för att förklara hur filterkontexten och radkontexten fortplantar sig med hjälp av relationer.

Innehållsförteckning

Radkontext och filterkontext i ett löpande totalt mått

Låt oss nu skapa ett löpande totalmått eftersom det innehåller både rad- och filterkontexter. Detta är ett grundläggande löpande totalmått, där jag använder COUNTROWS över FILTER, och funktionen ALLA för att returnera alla år som jag har i tabellen Datum. När jag tar med det måttet i tabellen nedan kan du se att vi får det resultat som vi förväntar oss.

Radkontext och filterkontext i en Lucky Templates DAX-kod

Låt oss nu försöka analysera hur den DAX-koden fungerar.

I måttet kan du se att först har vi COUNTROWS, men det är inte den första funktionen som utvärderas eller körs. Sedan har vi FILTER-funktionen och sedan ALL. Det första i utvärderingsordningen är ALLA. ALL returnerar alla unika värden för Dates Calendar Year Number genom att ignorera alla filterkontexter som finns utanför funktionen ALL.

Så i statistiken har vi kolumnen Kalenderårnummer, och den filtrerar aktivt den kolumnen. Men eftersom ALL kommer att ignorera den befintliga filterkontexten, kommer vi att få alla unika värden för den kolumnen.

I det andra argumentet, i radsammanhanget, har vi skrivit att datumkalenderårsnumret ska vara mindre än MAX datumkalenderårstalet. Nu, om du är nybörjare och fortfarande försöker förstå och lära dig DAX, kanske du tror att både referenserna på vänster sida och inuti MAX-funktionen tillhör samma kolumn och är samma tabell som vi har inuti ALL funktion.

Men det är inte sant. Den enda del av radkontexten som hör till ALL-funktionen är den som vi har på vänster sida. Den som vi har på MAX utvärderas i en filterkontext och inte i radkontexten.

Så, FILTER försöker skapa en radkontext på tabellen som du tillhandahåller i det första argumentet, och den här delen av koden hämtas faktiskt från just den radkontexten. Så varje rad, FILTER itererar tabellen som vi har inuti ALL, och sedan kan vi komma åt alla värden som vi för närvarande itererar.

Så i den första iterationen har vi bara ett värde. I den andra iterationen har vi det andra värdet. Men när vi skriver MAX är det oberoende av radkontexten som vi skapar med funktionen FILTER. Så MAX utvärderas i filterkontexten som skapas av det aktuella årstalet som vi har använt i den matrisen.

När vi är vid 2006 kommer MAX att returnera 2006 medan den aktuella raden kan vara 2006, 2007 eller 2008. FILTER kommer att returnera tabellen som uppfyller kriterierna som vi anger i det andra argumentet. När vi flyttar till 2007 kommer MAX att returnera 2007. Under 2008 kommer det att returnera 2008. Och beroende på alla värden som är mindre än värdet som returneras av MAX-funktionen, kommer FILTER att returnera en tabell.

För att bevisa att MAX inte är beroende av radkontexten kan vi dela upp denna bit av DAX-kod i flera variabler. Och då kommer vi att kunna förstå att kolumnreferensen på vänster sida och på höger sida inte är samma.

Så låt oss skapa en variabel.

Som du kan se i måttet nedan skapade jag tre variabler (). Jag la sedan till FILTER-koden till sist med en variabel Resultat som använder. När jag använder det här måttet i tabellen nedan ser du att ingenting förändras. Resultaten är fortfarande desamma. Vi får fortfarande samma löpande total som vi fick tidigare.

Radkontext och filterkontext i en Lucky Templates DAX-kod

Om vi ​​går tillbaka till koden och försöker hämta värdet på den första variabeln och bekräftar det kan du se att för varje rad får vi samma årtal.

Radkontext och filterkontext i en Lucky Templates DAX-kod

Så, förhoppningsvis, kunde jag förklara för dig att MAX-funktionen, i den här koden, faktiskt inte beror på det verkliga sammanhanget för dess värden. Och om du vill förenkla din förståelse av utvärderingskontexten kan du alltid dela upp koden i flera variabler så att du kan förstå utvärderingsordningen och hur koden exekveras.

Nu vill jag visa dig ett scenario där MAX-funktionen kommer att bero på radkontexten som skapas av FILTER-funktionen.

Så låt oss gå tillbaka till den åtgärden. Låt oss duplicera det, och istället för Senaste synliga året kommer jag att ha detMAX Datum Kalenderårsnummer. När jag tar in det i matrisen kan du se att vi får en blank.

Radkontext och filterkontext i en Lucky Templates DAX-kod

Varför?

Saken är att vi itererar alla år och vad BERÄKNA gör är att den konverterar den för närvarande itererade raden till en likvärdig filterkontext.

Om jag skriver ett likhetstecken här kan du se att vi får sju, sju och sju.

Varför?

Låt mig skapa en ny beräknad tabell så att du enkelt kan förstå vad som händer.

Radkontext och filterkontext i en Lucky Templates DAX-kod

Jag går och skapar ett nytt bord. Därefter ska jag skrivaöver ALLA datum kalenderårsnummer. Sedan skriver jag Max år, och sedan använder jag BERÄKNA över MAX för datumkalenderårsnummer. Och nu kan du se att vi upprepar samma värde för varje rad.

Radkontext och filterkontext i en Lucky Templates DAX-kod

Eftersom dessa siffror inte är strikt mindre än dem själva, får vi en blank. Men när vi använder lika med (=), säger vi att alla värden som är mindre än 2011 får en sjua.

Dessutom, även om du använder en måttreferens som något som Max Year, kommer den här koden inte att fungera.

Radkontext och filterkontext i en Lucky Templates DAX-kod

Om jag klickar på bekräfta kan du se att vi fortfarande inte får något. Detta beror på att när vi skriver Max år skriver vi helt enkelt BERÄKNA MAX Datum Kalenderårsnummer.

Radkontext och filterkontext i en Lucky Templates DAX-kod

En måttreferens har alltid en CALCULATE utanför sig. Så, detta mått initierar en kontextövergång som konverterar den för närvarande itererade raden till en filterkontext.

Men om du är bunden och du måste använda en måttreferens, vad du kan göra är att lagra det måttet i en variabel. Och som du kanske vet är variabler konstanta, och de kan inte skapa en kontextövergång. Så den kan inte konvertera radkontexten till en filterkontext.

Så det är en snabb demonstration av hur en radkontext och en filterkontext interagerar med varandra i en DAX-kod.

Låt oss nu gå till DAX Studio för att förstå vad som händer bakom kulisserna.

Använda DAX Studio för att förstå radkontext och filterkontext

Låt oss gå till de externa verktygen och starta DAX Studio. Vi måste ansluta till LuckyTemplates-filen med hjälp av Query Plan och Server Timings .

Sedan ska jag skapa ett frågemått. Jag skriver DEFINE MEASURE i datumtabellen, Datum löpande totalt. Och sedan ska jag använda den ursprungliga koden som vi hade.

Eftersom det är meningen att vi ska lämna tillbaka en tabell kan vi skriva EVALUATE. Slutligen ska vi skapa tabellen med SUMMARISECOLUMNS. Så vi kommer att skriva datum kalenderårnummer och den virtuella kolumnen, som kommer att vara den löpande summan. Och sedan kan jag skriva något som DT som ett DAX Studio-sökord.

Radkontext och filterkontext i en Lucky Templates DAX-kod

Om jag kör den här koden kan du se att koden är komplett och vi får fortfarande samma resultat som vi har sett inuti LuckyTemplates.

Radkontext och filterkontext i en Lucky Templates DAX-kod

Låt oss nu gå till frågeplanen för att förstå vad som händer bakom kulisserna. Låt oss se om MAX-funktionen faktiskt är beroende av radkontexten eller inte. Låt oss gå till den logiska frågeplanen eftersom den fysiska frågeplanen i allmänhet är mer komplex och är lite svår att läsa.

Radkontext och filterkontext i en Lucky Templates DAX-kod

Du kan se att den första operatorn på den första raden är GroupSemiJoin och som används av SUMMARISECOLUMNS för att skapa en inre skarv mellan två kolumner.

Sedan, för att gå med i dessa kolumner, finns det Scan_Vertipaq , som är lagringsmotorn som vi har i analystjänsterna. Vi kan se att det står att vi behöver en kolumn, vilket är Dates Calendar Year Number. I LuckyTemplates kan du se att på matrisen har vi den här kolumnen för kalenderårnummer, som fungerar som tillgång till vår rapport.

Därefter har vi COUNTROWS-funktionen i vårt mått som en toppnivåoperatör, sedan anropar COUNTROWSför filtret. Det finns en Scan_Vertipaq igen, som säger att RequiredCols är Dates Calendar Year Number.

Rad 2 och 5 är samma, men den första Scan_Vertipaq är markerad med noll medan den andra är med en. Det betyder att kolumnen som vi kommer åt, med hjälp av ALL-funktionen, extraheras separat från kolumnen som vi har inuti SUMMARIZECOLUMNS-funktionen.

Sedan finns det en LessThan- operatör. På nästa rad kan vi se att det finns en jämförelse mellan radkontexten och MAX-funktionen .

Detta följs av Max_Vertipaq . Så vi extraherar faktiskt Max-värdet från lagringsmotorn. Mot höger kan du se att det står, DependOnCols Dates Calendar Year Number. Detta är det viktigaste som vi behöver komma ihåg. Tidigare sa jag att det inte finns något beroende av MAX-funktionen på radkontexten, och det är detta som faktiskt bevisar det.

Och så, här står det noll.

Var hittade vi noll?

På toppen (den andra raden), som extraheras för SAMMANFATTNINGSKOLUMN. Det betyder att MAX-funktionen inte beror på radkontexten, utan den beror faktiskt på kolumnen (kalenderårsnummer) som vi har i den tabellen. Så den tabellen skapar faktiskt filterkontexten.

Kort sagt, MAX-funktionen är beroende av filterkontexten och inte radkontexten.

Därefter kan du se att för att beräkna Max_Vertipaq har vi en Scan_Vertipaq , som säger att DependOnCols noll (0) Datum Kalender Årsnummer. Och sedan finns det flera andra kolumner som kräver kolumner.

Låt oss nu titta på variabelversionen av koden. Istället för att returnera LastVisibleYear, kommer jag att returnera COUNTROWS-versionen eller Result-variabeln, och du kan se att vi fortfarande får samma resultat.

Radkontext och filterkontext i en Lucky Templates DAX-kod

Om vi ​​tittar på frågeplanen kan du se att den är lite längre, men den är mycket lättare att läsa.

Radkontext och filterkontext i en Lucky Templates DAX-kod

Slutligen, här är den beräknade versionen av koden också

Radkontext och filterkontext i en Lucky Templates DAX-kod

Och så här ser dess logiska frågeplan ut.

Radkontext och filterkontext i en Lucky Templates DAX-kod




Slutsats

I den här handledningen har jag förklarat hur en given funktion kan interagera och inte interagera med radkontexten. Jag har också visat dig hur MAX, i det här fallet, utvärderades i filterkontexten och inte i radkontexten.

Det är viktigt att alltid komma ihåg att filterkontexten filtrerar hela modellen och radkontexten bara itererar den givna tabellen och filtrerar aldrig modellen. Filterkontexten itererar inte en tabell.

Jag hoppas att du tyckte att den här handledningen var till hjälp. Håll utkik efter vårkod som vi kommer att släppa mycket snart. Vi kommer att gå mycket djupare in i liknande scenarier. Vi kommer också att lära dig hur du kan optimera din DAX-kod.


Pipe In R: Anslutningsfunktioner med Dplyr

Pipe In R: Anslutningsfunktioner med Dplyr

I den här handledningen kommer du att lära dig hur du kopplar ihop funktioner med hjälp av dplyr-röroperatorn i programmeringsspråket R.

RANKX Deep Dive: A Lucky Templates DAX-funktion

RANKX Deep Dive: A Lucky Templates DAX-funktion

RANKX från LuckyTemplates låter dig returnera rankningen av ett specifikt nummer i varje tabellrad som utgör en del av en lista med nummer.

Extrahera LuckyTemplates-teman och bilder från PBIX

Extrahera LuckyTemplates-teman och bilder från PBIX

Lär dig hur du tar isär en PBIX-fil för att extrahera LuckyTemplates-teman och bilder från bakgrunden och använda den för att skapa din rapport!

Excel Formler Fuskblad: Mellanvägledning

Excel Formler Fuskblad: Mellanvägledning

Excel Formler Fuskblad: Mellanvägledning

LuckyTemplates Kalendertabell: Vad är det och hur man använder det

LuckyTemplates Kalendertabell: Vad är det och hur man använder det

LuckyTemplates Kalendertabell: Vad är det och hur man använder det

Python i LuckyTemplates: Hur man installerar och ställer in

Python i LuckyTemplates: Hur man installerar och ställer in

Lär dig hur du installerar programmeringsspråket Python i LuckyTemplates och hur du använder dess verktyg för att skriva koder och visa bilder.

Beräkna dynamiska vinstmarginaler – enkel analys av LuckyTemplates med DAX

Beräkna dynamiska vinstmarginaler – enkel analys av LuckyTemplates med DAX

Lär dig hur du beräknar dynamiska vinstmarginaler vid sidan av LuckyTemplates och hur du kan få fler insikter genom att gräva djupare i resultaten.

Sortering av datumtabellkolumner i LuckyTemplates

Sortering av datumtabellkolumner i LuckyTemplates

Lär dig hur du sorterar fälten från en utökad datumtabells kolumner korrekt. Detta är en bra strategi att göra för svåra fält.

Hitta dina bästa produkter för varje region i LuckyTemplates med DAX

Hitta dina bästa produkter för varje region i LuckyTemplates med DAX

I den här artikeln går jag igenom hur du kan hitta dina toppprodukter per region med hjälp av DAX-beräkningar i LuckyTemplates, inklusive TOPN- och CALCULATE-funktionerna.

Skräpdimension: Vad är det och varför det är allt annat än skräp

Skräpdimension: Vad är det och varför det är allt annat än skräp

Lär dig hur du använder en skräpdimension för flaggor med låg kardinalitet som du vill infoga i din datamodell på ett effektivt sätt.