VAR 變量語法運用(5)
? ?1巢掺、變量作為DAX的篩選
? ? ?先來回顧一下:
?? ?(1)你應(yīng)該還記得,我們在前面的討論中說到:變量能構(gòu)建DAX的外部篩選器。這可能是書寫DAX 最需要的一個功能。比如蒸矛,我們討論過的,使用變量可以擺脫EARLIER函數(shù)的約束胸嘴。而EARLIER可能是 DAX學(xué)習(xí) 中必須要邁過去的一道坎雏掠。
? ? ? ?如果將變量理解為:存在于外部篩選器里被公式引用的計算。那么筛谚,它的含義更像是OUTER --“外部的”磁玉,而不是EARLIER --“更早的”:
Product[ListPriceRankDense] =
VAR??CurrentPrice = Product[Unit Price]
RETURN
COUNTROWS (
FILTER (VALUES ( Product[Unit Price] ),
?Product[Unit Price] > CurrentPrice??) ) + 1
? ? ? ?即便在這個表達式中,你也可以將這里的變量CurrentPrice理解為:它是在篩選器外部單獨計算的驾讲。因此,意思很明顯席赂,它先評估當(dāng)前?Product[Unit Price]--產(chǎn)品的價格(將該列保存為存儲數(shù)據(jù))吮铭,而后在?FILTER篩選器里面引用它,這時候它已經(jīng)是一個按定義得出的結(jié)果值颅停。所以谓晌,在此表達式中不再需要EARLIER。
? ? (2)變量使得復(fù)雜子表達式能被單個計算式替代癞揉,只要存在需要多次計算的相同子表達式時纸肉,使用變量定義該計算式來作為DAX 優(yōu)化器,從而保證計算只發(fā)生一次喊熟,以產(chǎn)生更快的代碼柏肪。
? ? (3)通過前面兩點的復(fù)習(xí),第一芥牌,變量能構(gòu)建篩選器(盡管是外部的)烦味,第二,能使用一個變量替代同一表達式的重復(fù)引用壁拉。我們回憶一下DAX的兩個重要的概念:篩選+計算谬俄。變量能虛擬出需要的行或列篩選柏靶,也就是說,每當(dāng)DAX中需要一個列表篩選時溃论,你就定義一個列表變量指代它屎蜓,同樣,需要一個“當(dāng)前行”行篩選時钥勋,你就定義一個變量來指代它……梆靖。依次類推,直到需要的所有篩選列表都具備時笔诵,再將它們 RETURN 取出來組裝成DAX的篩選返吻。這有利于DAX的步驟思考以及按邏輯簡化公式的復(fù)雜過程。這就是我們前面所說的:
? ? ? ?使用變量的最重要的原因是能按步驟書寫DAX公式乎婿,以及提高公式的可讀性测僵。?為DAX計算的一些中間步驟提供一個變量名稱,這是編寫DAX 代碼的很好的方法谢翎。
? ? 2捍靠、補充與注意事項
? ? ? ?雖然變量存在諸多方面的好處,但使用中也需要注意幾個方面森逮,這在前面也有一點提示(某些情況下不能使用變量---比如需要回到原數(shù)據(jù)列表的計算式)榨婆。
? ? ? (1)補充:VAR在EVALUATE中的應(yīng)用(DAX Studio等取出數(shù)據(jù)的方式)
? ? ? ?可以在EVALUATE語句中定義變量,其語法與用于變量定義的標(biāo)準(zhǔn)語法略有不同褒侧。我們已經(jīng)知道良风,通常使用VAR來定義一個變量,再由RETURN返回后的表達式訪問先前定義的該變量闷供。這樣的標(biāo)準(zhǔn)語法烟央,可以替換DAX中的任何標(biāo)量值或表表達式。
? ? ? ?但是歪脏,當(dāng)編寫EVALUATE語句時疑俭,也是在定義部分中定義一個變量,但不必在之后寫入RETURN:
DEFINE
VAR ExpensiveProducts = FILTER ( Product婿失, Product[Unit Price]> 3000 )
EVALUATE
CALCULATETABLE ( Product钞艇, ExpensiveProducts )
因此,EVALUATE的一個更完整的帶變量的語法定義如下:
? ? ? ?在任何情況下豪硅,只有在EVALUATE之后的表表達式中使用變量時哩照,才會對該變量進行計值,并且計值不依賴于變量定義之后進行的當(dāng)前篩選操作舟误。換句話說葡秒,可以在EVALUATE之后使用VAR / RETURN標(biāo)準(zhǔn)變量語法。
? ? ? ?這不難理解:EVALUATE是直接從數(shù)據(jù)模型里查詢數(shù)據(jù)(先有壓縮數(shù)據(jù)再有存儲數(shù)據(jù)),變量是存儲數(shù)據(jù)眯牧,同時也是數(shù)據(jù)模型的一部分蹋岩。因此,EVALUATE能置于RETURN的前面用以取出變量數(shù)據(jù)学少,反之剪个,則不行)。如下例所示:
EVALUATE
VAR? ExpensiveProducts = FILTER ( Product版确, Product[Unit Price] > 3000 )
RETURN
CALCULATETABLE ( Product扣囊, ExpensiveProducts )
? ?(2)變量的惰性
? ? ? ? 一方面,變量的使用會帶來更有效的公式執(zhí)行绒疗,是因為變量減少了公式引擎和原數(shù)據(jù)之間的“往返”(比如遍歷侵歇、迭代列表。然而吓蘑,變量能直接被公式引擎引用惕虑,即只需請求一次計算)。而且磨镶,變量能作為計算式的公用篩選器溃蔫。
? ? ? ?另一方面,不僅在計算式中使用變量琳猫,如果在 DAX 中查詢數(shù)據(jù)模型(篩選)伟叛,也應(yīng)考慮使用變量來簡化代碼。比如脐嫂,當(dāng)需要使用多個計算語句來獲取多個結(jié)果子集時统刮,還應(yīng)考慮哪些變量可以在多個查詢中被使用…..。
? ? ? ?值得提醒的是雹锣,無論是以上兩個情況的哪一種网沾,在一個或多個計算語句之前,某個定義語句只能出現(xiàn)一次:一個變量可以在一個計算式被反復(fù)引用蕊爵,但一個變量不能存在于多個不同的計算式里(比如在一個度量里的變量,不能用于另外一個度量(其實根本就不會出現(xiàn))桦山,或者在一個計算中攒射,RETURN之后如果還需要引用該變量,則需要重新定義恒水。即變量只存在于當(dāng)前定義下的計算式中)
? ? ? ? 我們通過幾個DAX表達式來加深理解:
? ? ? 下圖中会放,我們定義了兩個在計算式中使用的變量:Date01與Date03,當(dāng)在RETURN之后的計算式里使用它們時钉凌,智能提示里會出現(xiàn)剛剛定義的這兩個變量名咧最,只需雙擊引用即可。
? ? ? ?但是,當(dāng)你在另一個度量(任何其他度量書寫)計算里想再次引用該變量時矢沿,是不會存在Date01與Date03的滥搭。當(dāng)然,最通俗的理解是:變量 ≠ 度量捣鲸。 ?例如, 下面的代碼定義了在兩個不同的CALCULATE語句中用作篩選器的變量 :
DEFINE
VAR Selected_Colors =?FILTER (ALL ( 'Product'[Color] ),
?'Product'[Color] IN { "Purple", "Azure" })?
EVALUATE
CALCULATETABLE (?'Product',??Selected_Colors)
? ? ? ?當(dāng)變量的定義遵循計算語法時瑟匆,其作用區(qū)域僅限于作為計算語句引用的表表達式。下面的示例僅第一個計算語句定義的 SelectedColors 變量有效栽惶,而在其接下來的計算語句中對該變量的引用將失敗 (請參見第10行 )愁溜, 因為該變量不可再次被訪問。
?EVALUATE
VAR Selected_Colors =
FILTER ( ?ALL ( 'Product'[Color] ),
?'Product'[Color] IN { "Purple", "Azure" })
RETURN
CALCULATETABLE (?'Product',?Selected_Colors) ?
EVALUATE
RETURN? ? -- 再次引用
CALCULATETABLE (
VALUES ( 'Product'[Brand] ),??Selected_Colors) – 不起作用
? ? ? ?雖然外厂,我們期望通過?EVALUATE冕象,再次引用?Selected_Colors這個變量,但由于該變量已在第一個?RETURN 后的CALCULATETABLE計算列表里被引用汁蝶,不能再次被引用(只計算一次)渐扮。
? ? ? ?有人把變量的這種一次性的引用計算、更像“常量”的行為稱為:變量的“惰性”穿仪。
? ? ? ?基于此席爽, 你可以在前面的公式中的每個計算語句里分別定義一個變量,如下面的示例所示啊片,變量 SelectColors 被計算兩次(定義了兩次)只锻。
EVALUATE
VAR SelectedColors =
FILTER ( ALL ( 'Product'[Color] ),
? 'Product'[Color] IN { "Purple", "Azure" })
RETURN
CALCULATETABLE ('Product',?SelectedColors)?
?EVALUATE
VAR SelectedColors =
FILTER (ALL ( 'Product'[Color] ),
?'Product'[Color] IN { "Purple", "Azure" })? – 相同的變量被再次定義
RETURN
CALCULATETABLE (
?VALUES ( 'Product'[Brand] ),??SelectedColors)
? ? ? ?前面這個公式中,相同的變量被再次定義使用紫谷。之外齐饮,定義的變量(相同的變量名稱)可以在計算或任何其他 DAX 表達式中被重新定義,其定義的表達式可以相同或不同笤昨。
? ? ? ?在下面的示例中祖驱,第一個計算返回SelectedColors 變量定義的"Purple"紫色或"Azure"天藍色的顏色產(chǎn)品,而第二個計算則使用相同名稱的SelectedColors 變量的另一個定義瞒窒,其中表達式只包括"Red"紅色和"White"白色的顏色產(chǎn)品捺僻。
DEFINE
VAR Selected_Colors =
FILTER (ALL ( 'Product'[Color] ),?'Product'[Color] IN { "Purple", "Azure" })
EVALUATE
CALCULATETABLE (??'Product',?Selected_Colors) ?
EVALUATE
VAR Selected_Colors =
FILTER ( ALL ( 'Product'[Color] ),??'Product'[Color] IN { "Red", "White" })
RETURN
CALCULATETABLE (?'Product',??Selected_Colors)?
我們用更清晰的圖示來表示它:
? ? ? ?在"Power BI" 中,你可以在 "定義" 部分中聲明許多變量崇裁,因此它可以在不同的查詢中重復(fù)使用不同的可視對象的相同名稱的變量匕坯。這些變量通常應(yīng)用于報表中的可視對象展示的篩選器。
未完待續(xù)