A ORDERBY, PARTITIONBY, andMATCHBY függvények ismertetése
A DAXORDERBY, PARTITIONBY, andMATCHBY függvényei olyan speciális függvények, amelyek csak DAXWindow függvényekkel együtt használhatók: INDEX, OFFSET, WINDOW, RANK, ROWNUMBER.
A ORDERBY, PARTITIONBY, andMATCHBY megértése kritikus fontosságú a Window függvények sikeres használatához. Az itt szereplő példák OFFSEThasználnak, de a többi Window függvényre is érvényesek.
Forgatókönyv
Kezdjük egy példával, amely nem Window függvényeket használ a all. Az alábbiakban egy táblázat látható, amely a teljes értékesítést adja vissza színenként, calendaryear. Ezt a táblázatot többféleképpen is define, de mivel szeretnénk megérteni, hogy mi történik DAX, egy számított táblát használunk. A táblakifejezés a következő:
BasicTable =
SUMMARIZECOLUMNS (
DimProduct[Color],
DimDate[CalendarYear],
"CurrentYearSales", ROUND ( SUM ( FactInternetSales[SalesAmount] ), 0 )
)
Ez a számított táblakifejezés a FactInternetSales tábla SalesAmount oszlopának SUM végrehajtásához használja az SUMMARIZECOLUMNS és calculate kifejezéseket, a DimProduct tábla Szín oszlopát figyelembe véve, valamint a DimDate tábla CalendarYear oszlopát is and. Az eredmény a következő:
Szín | naptári év | Idei Értékesítések |
---|---|---|
"Fekete" | 2017 | 393885 |
"Fekete" | 2018 | 1818835 |
"Fekete" | 2019 | 3981638 |
"Fekete" | 2020 | 2644054 |
"Kék" | 2019 | 994448 |
"Kék" | 2020 | 1284648 |
"Több" | 2019 | 48622 |
"Több" | 2020 | 57849 |
"NA" | 2019 | 207822 |
"NA" | 2020 | 227295 |
"Piros" | 2017 | 2961198 |
"Piros" | 2018 | 3686935 |
"Piros" | 2019 | 900175 |
"Piros" | 2020 | 176022 |
Ezüst | 2017 | 326399 |
Ezüst | 2018 | 750026 |
Ezüst | 2019 | 2165176 |
Ezüst | 2020 | 1871788 |
Fehér | 2019 | 2517 |
Fehér | 2020 | 2589 |
"Sárga" | 2018 | 163071 |
"Sárga" | 2019 | 2072083 |
"Sárga" | 2020 | 2621602 |
Now, tegyük fel, hogy megpróbáljuk megoldani az értékesítési különbség kiszámításának üzleti kérdését, year-over-year minden színhez. Gyakorlatilag módot kell keresnünk arra, hogy find az azonos színű értékesítéseket a previousyearand kivonjuk az aktuális yearértékesítéséből a kontextusban. Például a [Red, 2019] kombináció esetén a [Red, 2018] értékesítéseit keressük. Ha ez megvan, kivonhatjuk az aktuális értékesítésből, és and visszaadjuk a szükséges value.
A OFFSET használata
OFFSET tökéletes a tipikus összehasonlításhoz szükséges previous típusú számításokra, amelyek szükségesek a fent leírt üzleti kérdés megválaszolásához, mivel lehetővé teszi számunkra, hogy relatív mozgást hajtsunk végre. A mi first kísérletünk a következő lehet:
1stAttempt =
VAR vRelation = SUMMARIZECOLUMNS (
DimProduct[Color],
DimDate[CalendarYear],
"CurrentYearSales", ROUND ( SUM ( FactInternetSales[SalesAmount] ), 0 )
)
RETURN
ADDCOLUMNS (
vRelation,
"PreviousColorSales",
SELECTCOLUMNS (
OFFSET (
-1,
vRelation
),
[CurrentYearSales]
)
)
Sok minden történik ezzel a kifejezéssel. Korábban használtuk a táblázat ADDCOLUMNS és expand módosítására egy PreviousColorSales nevű oszloppal. Az oszlop tartalma a CurrentYearSales értékre van állítva, amely SUM(FactInternetSales[SalesAmount]) a previous színhez (OFFSEThasználatával kérhető le).
Az eredmény a következő:
Szín | Naptári év | Jelenlegi Év Eladásai | ElőzőSzínEladások |
---|---|---|---|
"Fekete" | 2017 | 393885 | |
"Fekete" | 2018 | 1818835 | 393885 |
"Fekete" | 2019 | 3981638 | 1818835 |
"Fekete" | 2020 | 2644054 | 3981638 |
"Kék" | 2019 | 994448 | 2644054 |
"Kék" | 2020 | 1284648 | 994448 |
Több | 2019 | 48622 | 1284648 |
Több | 2020 | 57849 | 48622 |
"NA" | 2019 | 207822 | 57849 |
"NA" | 2020 | 227295 | 207822 |
"Piros" | 2017 | 2961198 | 227295 |
"Piros" | 2018 | 3686935 | 2961198 |
"Piros" | 2019 | 900175 | 3686935 |
"Piros" | 2020 | 176022 | 900175 |
"Ezüst" | 2017 | 326399 | 176022 |
Ezüst | 2018 | 750026 | 326399 |
Ezüst | 2019 | 2165176 | 750026 |
Ezüst | 2020 | 1871788 | 2165176 |
Fehér | 2019 | 2517 | 1871788 |
Fehér | 2020 | 2589 | 2517 |
"Sárga" | 2018 | 163071 | 2589 |
"Sárga" | 2019 | 2072083 | 163071 |
"Sárga" | 2020 | 2621602 | 2072083 |
Ez egy lépéssel közelebb áll a célunkhoz, de if alaposan megnézzük, nem egyezik pontosan azzal, amit keresünk. A [Silver, 2017] esetében például a PreviousColorSales értéke [Piros, 2020].
ORDERBY hozzáadása
Ez a fenti definíció a következőnek felel meg:
1stAttemptWithORDERBY =
VAR vRelation = SUMMARIZECOLUMNS (
DimProduct[Color],
DimDate[CalendarYear],
"CurrentYearSales", ROUND ( SUM ( FactInternetSales[SalesAmount] ), 0 )
)
RETURN
ADDCOLUMNS (
vRelation,
"PreviousColorSales",
SELECTCOLUMNS (
OFFSET (
-1,
vRelation,
ORDERBY ([Color], ASC, [CalendarYear], ASC, [CurrentYearSales], ASC)
),
[CurrentYearSales]
)
)
Ebben az esetben a OFFSET hívása ORDERBY használatával rendezi a táblázatot a Color and CalendarYear sorrendben növekvő sorrendben, amely meghatározza, hogy mi tekinthető a visszaadott previous sornak.
Ennek a két eredménynek az az oka, hogy ORDERBY automatikusan containsall oszlopokat a PARTITIONBYnem szereplő relációból. Mivel PARTITIONBY nincs megadva, a ORDERBY a Color (Naptárév) értékre van állítva, and CurrentYearSales értékre. Mivel azonban a relációban a Color and CalendarYear párok egyediek, a CurrentYearSales hozzáadása nem változtatja meg az eredményt. A fact, evenif-ben az volt a feladat, hogy csak a színt adjuk meg ORDERBY-ban, az eredmények megegyeznek, mivel a CalendarYear automatikusan hozzáadódik. Ennek az az oka, hogy a függvény annyi oszlopot ad hozzá a ORDERBY-hoz, amennyi szükséges annak érdekében, hogy az egyes sorokat egyedileg azonosíthassa a ORDERBYandPARTITIONBY oszlopok alapján.
1stAttemptWithORDERBY =
VAR vRelation = SUMMARIZECOLUMNS (
DimProduct[Color],
DimDate[CalendarYear],
"CurrentYearSales", ROUND ( SUM ( FactInternetSales[SalesAmount] ), 0 )
)
RETURN
ADDCOLUMNS(
vRelation,
"PreviousColorSales",
SELECTCOLUMNS (
OFFSET (
-1,
vRelation,
ORDERBY ([Color])
),
[CurrentYearSales]
)
)
PARTITIONBY hozzáadása
UsingPARTITIONBY =
VAR vRelation = SUMMARIZECOLUMNS (
DimProduct[Color],
DimDate[CalendarYear],
"CurrentYearSales", ROUND ( SUM ( FactInternetSales[SalesAmount] ), 0 )
)
RETURN
ADDCOLUMNS (
vRelation,
"PreviousColorSales",
SELECTCOLUMNS (
OFFSET (
-1,
vRelation,
ORDERBY ([CalendarYear]),
PARTITIONBY ([Color])
),
[CurrentYearSales]
)
)
Vegye észre, hogy a ORDERBY megadása itt nem kötelező, mert a ORDERBY automatikusan containsall a reláció azon oszlopait, amelyek nincsenek megadva a PARTITIONBY-ben. A következő kifejezés tehát ugyanazokat az eredményeket adja vissza, mert a ORDERBY a CalendarYear and CurrentYearSales értékre van állítva automatikusan:
UsingPARTITIONBYWithoutORDERBY =
VAR vRelation = SUMMARIZECOLUMNS (
DimProduct[Color],
DimDate[CalendarYear],
"CurrentYearSales", ROUND ( SUM ( FactInternetSales[SalesAmount] ), 0 )
)
RETURN
ADDCOLUMNS (
vRelation,
"PreviousColorSales",
SELECTCOLUMNS (
OFFSET (
-1,
vRelation,
PARTITIONBY ([Color])
),
[CurrentYearSales]
)
)
Jegyzet
Bár a ORDERBY a CalendarYear and CurrentYearSales értékre van állítva automatikusan, nincs garancia arra nézve, hogy milyen sorrendben lesznek hozzáadva. A If CurrentYearSales a CalendarYear elé kerül, ezért a kapott sorrend nem felel meg a várakozásoknak. A ORDERBYandPARTITIONBY megadásakor explicit módon and váratlan eredmények.
Mindkét kifejezés a következő eredményt adja vissza:
Szín | Naptári Év | Jelenlegi Év Értékesítései | Előző évi értékesítés ugyanarra a színre |
---|---|---|---|
"Fekete" | 2017 | 393885 | |
"Fekete" | 2018 | 1818835 | 393885 |
"Fekete" | 2019 | 3981638 | 1818835 |
"Fekete" | 2020 | 2644054 | 3981638 |
"Kék" | 2019 | 994448 | |
"Kék" | 2020 | 1284648 | 994448 |
Több | 2019 | 48622 | |
Több | 2020 | 57849 | 48622 |
"NA" | 2019 | 207822 | |
"NA" | 2020 | 227295 | 207822 |
"Piros" | 2017 | 2961198 | |
"Piros" | 2018 | 3686935 | 2961198 |
"Piros" | 2019 | 900175 | 3686935 |
"Piros" | 2020 | 176022 | 900175 |
Ezüst | 2017 | 326399 | |
Ezüst | 2018 | 750026 | 326399 |
Ezüst | 2019 | 2165176 | 750026 |
Ezüst | 2020 | 1871788 | 2165176 |
Fehér | 2019 | 2517 | |
Fehér | 2020 | 2589 | 2517 |
"Sárga" | 2018 | 163071 | |
"Sárga" | 2019 | 2072083 | 163071 |
"Sárga" | 2020 | 2621602 | 2072083 |
Ahogy ebben a táblázatban látható, a PreviousYearSalesForSameColor oszlop az azonos színű previousyear értékesítéseit jeleníti meg. A [Red, 2020] esetében a [Red, 2019] értékesítéseit adja vissza, and és így tovább. If nincs previousyear, például a [Red, 2017] esetében, nincs value visszaadva.
Úgy tekinthet a(z) PARTITIONBY-ra, mint a táblázat olyan részekre divide-ére, amelyekben végrehajthatja a(z) OFFSET számítást. A fenti példában a táblázat annyi részre van osztva, amennyi szín van, egy-egy színre. Ezután minden egyes részben a OFFSET kiszámításra kerül, majd a naptári év szerint rendezve lesz.
Vizuálisan a következő történik:
táblázat, amely CalendarYear szerint mutatja a -t
First, a PARTITIONBY hívása azt eredményezi, hogy a táblázat részekre van osztva, egy-egy színre. Ezt a táblázat képének világoskék mezői jelölik. Next, ORDERBY gondoskodik arról, hogy az egyes részeket naptárév szerint rendezze (a narancssárga nyilak jelölik). Végül a rendezett részek mindegyikében, minden sor esetén, OFFSET megkeresi a fölötte lévő sort, majd and ezt visszaadja a PreviousYearSalesForSameColor oszlopban value. Mivel minden first sornál nincs previous sor ugyanabban a részben, a PreviousYearSalesForSameColor oszlopban lévő eredmény üres.
A végső eredmény eléréséhez egyszerűen ki kell vonnunk a CurrentYearSales-t a previousyear azon színre vonatkozó értékesítéséből, amelyet a OFFSEThívás adott vissza. Mivel not szeretnénk az previousyear értékesítéseket ugyanahhoz a színhez, de csak az aktuális year értékesítésekben and a year különbséget year. Íme az utolsó számított táblakifejezés:
FinalResult =
VAR vRelation = SUMMARIZECOLUMNS (
DimProduct[Color],
DimDate[CalendarYear],
"CurrentYearSales", ROUND ( SUM ( FactInternetSales[SalesAmount] ), 0 )
)
RETURN
ADDCOLUMNS (
vRelation,
"YoYSalesForSameColor",
[CurrentYearSales] -
SELECTCOLUMNS (
OFFSET (
-1,
vRelation,
ORDERBY ([CalendarYear]),
PARTITIONBY ([Color])
),
[CurrentYearSales]
)
)
And itt van ennek a kifejezésnek az eredménye:
Szín | Naptári év | Aktuális évi értékesítés | YoYSalesForSameColor |
---|---|---|---|
"Fekete" | 2017 | 393885 | 393885 |
"Fekete" | 2018 | 1818835 | 1424950 |
"Fekete" | 2019 | 3981638 | 2162803 |
"Fekete" | 2020 | 2644054 | -1337584 |
"Kék" | 2019 | 994448 | 994448 |
"Kék" | 2020 | 1284648 | 290200 |
Több | 2019 | 48622 | 48622 |
Több | 2020 | 57849 | 9227 |
"NA" | 2019 | 207822 | 207822 |
"NA" | 2020 | 227295 | 19473 |
"Piros" | 2017 | 2961198 | 2961198 |
Vörös | 2018 | 3686935 | 725737 |
"Piros" | 2019 | 900175 | -2786760 |
"Piros" | 2020 | 176022 | -724153 |
Ezüst | 2017 | 326399 | 326399 |
Ezüst | 2018 | 750026 | 423627 |
Ezüst | 2019 | 2165176 | 1415150 |
Ezüst | 2020 | 1871788 | -293388 |
Fehér | 2019 | 2517 | 2517 |
"Fehér" | 2020 | 2589 | 72 |
"Sárga" | 2018 | 163071 | 163071 |
"Sárga" | 2019 | 2072083 | 1909012 |
"Sárga" | 2020 | 2621602 | 549519 |
A MATCHBY használata
Észrevehette, hogy nem adtuk meg MATCHBY a all-nél. Ebben az esetben nem szükséges. A ORDERBYandPARTITIONBY oszlopai (amennyiben a fenti példákban meg vannak adva) elegendőek az egyes sorok egyedi azonosításához. Mivel nem specifikáltunk MATCHBY-t, a ORDERBYandPARTITIONBY megadott oszlopok a sorok egyedi azonosítására szolgálnak, így azok összehasonlíthatók, hogy OFFSET jelentős eredményt adjon. If a ORDERBYandPARTITIONBY oszlopai nem azonosítják egyedileg az egyes sorokat, további oszlopok is hozzáadhatók a ORDERBY záradékhoz, if ezek a további oszlopok lehetővé teszik az egyes sorok egyedi azonosítását. If lehetséges not egy error ad vissza. Ebben a last esetben a MATCHBY megadása segíthet a errormegoldásában.
If MATCHBY meg van adva, a MATCHBYandPARTITIONBY oszlopai az egyes sorok egyedi azonosítására szolgálnak. If ha lehetséges, not egyet error ad vissza. Even if MATCHBY nem szükséges, fontolja meg a MATCHBY explicit megadását a félreértések elkerülése érdekében.
A fenti példákat folytatva az alábbi last kifejezés látható:
FinalResult =
VAR vRelation = SUMMARIZECOLUMNS (
DimProduct[Color],
DimDate[CalendarYear],
"CurrentYearSales", ROUND ( SUM ( FactInternetSales[SalesAmount] ), 0 )
)
RETURN
ADDCOLUMNS (
vRelation,
"YoYSalesForSameColor",
[CurrentYearSales] -
SELECTCOLUMNS (
OFFSET (
-1,
vRelation,
ORDERBY ([CalendarYear]),
PARTITIONBY ([Color])
),
[CurrentYearSales]
)
)
If szeretnénk explicit módon meghatározni a sorok egyedi azonosítását, MATCHBY az alábbi egyenértékű kifejezésben látható módon adhatjuk meg:
FinalResultWithExplicitMATCHBYOnColorAndCalendarYear =
VAR vRelation = SUMMARIZECOLUMNS (
DimProduct[Color],
DimDate[CalendarYear],
"CurrentYearSales", ROUND ( SUM ( FactInternetSales[SalesAmount] ), 0 )
)
RETURN
ADDCOLUMNS (
vRelation,
"YoYSalesForSameColor",
[CurrentYearSales] -
SELECTCOLUMNS (
OFFSET (
-1,
vRelation,
ORDERBY ([CalendarYear]),
PARTITIONBY ([Color]),
MATCHBY ([Color], [CalendarYear])
),
[CurrentYearSales]
)
)
Mivel MATCHBY van megadva, a MATCHBY és a PARTITIONBY megadott oszlopok egyaránt a sorok egyedi azonosítására szolgálnak. Mivel a szín a MATCHBYandPARTITIONBYmindegyikében meg van adva, a következő kifejezés egyenértékű a previous kifejezéssel:
FinalResultWithExplicitMATCHBYOnCalendarYear =
VAR vRelation = SUMMARIZECOLUMNS (
DimProduct[Color],
DimDate[CalendarYear],
"CurrentYearSales", ROUND ( SUM ( FactInternetSales[SalesAmount] ), 0 )
)
RETURN
ADDCOLUMNS (
vRelation,
"YoYSalesForSameColor",
[CurrentYearSales] -
SELECTCOLUMNS (
OFFSET (
-1,
vRelation,
ORDERBY ([CalendarYear]),
PARTITIONBY ([Color]),
MATCHBY ([CalendarYear])
),
[CurrentYearSales]
)
)
Mivel a MATCHBY megadása nem szükséges az eddig megvizsgált példákban, nézzünk meg egy kicsit más példát, amely MATCHBYigényel. Ebben az esetben a rendelési sorok listája van. Minden sor egy rendeléssort jelöl. A rendelések több rendeléssort is tartalmazhatnak, and 1. rendeléssor számos rendelésen megjelenik. Emellett minden rendeléssorhoz tartozik egy ProductKey and és egy SalesAmount. A táblázat megfelelő oszlopainak sample a következőképpen néz ki:
Értékesítési rendelés száma | Értékesítési rendelés sor szám | Termékkulcs | Eladási Összeg |
---|---|---|---|
SO51900 | 1 | 528 | 4,99 |
SO51948 | 1 | 528 | 5.99 |
SO52043 | 1 | 528 | 4.99 HUF |
SO52045 | 1 | 528 | 4.99 |
SO52094 | 1 | 528 | 4.99 |
SO52175 | 1 | 528 | 4.99 |
SO52190 | 1 | 528 | 4.99 |
SO52232 | 1 | 528 | 4,99 |
SO52234 | 1 | 528 | 4.99 |
SO52234 | 2 | 529 | 3.99 |
Figyelje meg, hogy a SalesOrderNumber and SalesOrderLineNumber mind a sorok egyedi azonosításához szükséges.
Minden rendeléshez a SalesAmount által csökkenő sorrendben megrendelt ugyanazon product (a ProductKey által képviselt) previous értékesítési összeget szeretnénk visszaadni. A következő kifejezés nem fog működni, mert a vRelationban több sor is lehet, mivel az át lett adva OFFSET:
ThisExpressionFailsBecauseMATCHBYIsMissing =
ADDCOLUMNS (
FactInternetSales,
"Previous Sales Amount",
SELECTCOLUMNS (
OFFSET (
-1,
FactInternetSales,
ORDERBY ( FactInternetSales[SalesAmount], DESC ),
PARTITIONBY ( FactInternetSales[ProductKey] )
),
FactInternetSales[SalesAmount]
)
)
Ez a kifejezés a error-át adja vissza: "AOFFSETkapcsolat paramétere ismétlődő sorokat tartalmazhat, ami nem megengedett."
A kifejezés működéséhez meg kell adni MATCHBY, andall oszlopokat kell tartalmaznia, amelyek egyedileg define egy sort. itt MATCHBY szükséges, mert a FactInternetSales reláció nem tartalmaz explicit kulcsokat or egyedi oszlopokhoz. A SalesOrderNumber and SalesOrderLineNumber oszlopok azonban egy összetett kulcsot alkotnak, ahol a relációban egyedi a létezésük, and ezért egyedien azonosíthatják az egyes sorokat. A SalesOrderNumber or SalesOrderLineNumber megadása nem elegendő, mivel mindkét oszlop ismétlődő valuestartalmaz. A következő kifejezés megoldja a problémát:
ThisExpressionWorksBecauseOfMATCHBY =
ADDCOLUMNS (
FactInternetSales,
"Previous Sales Amount",
SELECTCOLUMNS (
OFFSET (
-1,
FactInternetSales,
ORDERBY ( FactInternetSales[SalesAmount], DESC ),
PARTITIONBY ( FactInternetSales[ProductKey] ),
MATCHBY ( FactInternetSales[SalesOrderNumber],
FactInternetSales[SalesOrderLineNumber] )
),
FactInternetSales[SalesAmount]
)
)
And ez a kifejezés valóban a következő eredményeket adja vissza:
Rendelésszám | ÉrtékesítésiRendelésSorSzám | termékkulcs | Eladási összeg | Previous értékesítési összeg |
---|---|---|---|---|
SO51900 | 1 | 528 | 5.99 | |
SO51948 | 1 | 528 | 4,99 | 5.99 |
SO52043 | 1 | 528 | 4.99 | 4.99 |
SO52045 | 1 | 528 | 4.99 | 4,99 |
SO52094 | 1 | 528 | 4,99 | 4.99 |
SO52175 | 1 | 528 | 4.99 | 4.99 |
SO52190 | 1 | 528 | 4.99 | 4.99 |
SO52232 | 1 | 528 | 4.99 | 4.99 |
SO52234 | 1 | 528 | 4.99 | 4.99 |
SO52234 | 2 | 529 | 3.99 |
Related tartalom
ORDERBY PARTITIONBY MATCHBY INDEX OFFSET WINDOW RANK ROWNUMBER