DAX專題:11 DAX中的變量-Variables in DAX-讀書筆記(19)

提示:因代碼格式需要,本章內(nèi)容代碼示例使用了較多的Tab,使用手機(jī)觀看可能會有些怪,在電腦觀看效果更好。
本章向大家介紹DAX中變量的概念,2015年以來DAX語言就有了變量這個功能。如果你有編程經(jīng)驗的話,很容易理解什么是變量。如果你沒有編程基礎(chǔ),那么你肯定應(yīng)該理解數(shù)學(xué)方程中的未知數(shù)的概念,我們假設(shè):X = 5 ,Y = 3, 那么X + Y等多少呢?在這個例子中,X + Y = 8,因為X被賦予了一個值5,Y被賦值為3。這個令X,Y等于多少的概念,就是DAX中變量的工作方式。DAX中使用變量時,也要先給變量起一個名字,再給它賦予一個值(這里的值是廣義上的值的概念,這個值可以是一個表,也可以是一個具體的值,還可以是一個返回一個值的表達(dá)式等),然后可以在其它DAX公式中就可以使用這個變量了,就像剛剛舉的X+Y的樣子。
一、使用變量的規(guī)則 Rules for Using Variables
Here are a few simple rules related to using variables in DAX:
? You assign a variable by using the VAR keyword with the following syntax:
VAR variableName = <something>
? You can create as many variables as you want in a formula. You must define them all before using the?
RETURN keyword.
? There is no comma after each defined variable. (You will see this below.)
? After you define at least one variable name, you must use the keyword RETURN to complete the?
formula.
? Variables can be values or tables.
? A variable name cannot begin with an integer as the first character, but you can use integers as sub-
sequent characters in a name (e.g., 1stYear is not allowed, but Year1 is fine).
? Variable names cannot contain special characters (e.g., %)
? Variable names cannot be reserved words, such as function names.
? Once a variable has been assigned a value, that value cannot change prior to the RETURN keyword.
? Variables are local in scope to the formula. You cannot refer to a variable declared in one measure?
from within a different measure.
??使用VAR關(guān)鍵字賦值變量,語法如下:VAR variableName =<something>
??你可以在公式中創(chuàng)建任意多的變量,在使用RETURN關(guān)鍵字之前,必須全部定義它們。
??每個定義的變量后面沒有逗號。
??定義至少一個變量名后,必須使用關(guān)鍵字RETURN來完成公式。
??變量可以是值或表。
??變量名不能為漢字,不能以數(shù)字開頭,但可以使用整數(shù)作為后面的字符(例如,不允許使用1stYear,但可以使用Year1)。
??變量名不能包含特殊字符(如%)。
??變量名不能為保留字,如函數(shù)名。
??一旦變量被賦值,該值不能在RETURN關(guān)鍵字之前更改。
??變量在公式中是局部的。不能在一個度量中引用另一個度量中的變量。
二、變量用法示例:求上一年的銷售額 Total Sales MAT Revisited
在第16章中我們寫過一個度量值用于求上一年的銷售額
Total Sales MAT Improved =
? ? IF(MAX('Calendar'[Date])>=DATE(2017,7,1),
? ? ? ? CALCULATE([Total Sales],
? ? ? ? ? ? FILTER(ALL('Calendar'),
? ? ? ? ? ? ? ? 'Calendar'[Date] > MAX('Calendar'[Date]) - 365
? ? ? ? ? ? ? ? && 'Calendar'[Date] <= MAX('Calendar'[Date])
? ? ? ? ? ? )
? ? ? ? )
? ? )
現(xiàn)在讓我們看看如何用變量改寫上面的代碼。仔細(xì)看看下面的公式,你會發(fā)現(xiàn)什么呢?(代碼使用DAX Formatter工具進(jìn)行了格式化,可以使用行號對公式進(jìn)行解讀。)
1 ????Total sales MAT Improved with Variables =
2???? ????VAR StartMAT =
3 ???? ????????DATE (2017,7,1 )
4 ????????VAR unfilteredCalendar =
5 ???? ????????ALL ( 'calendar ')
6 ????????VAR endDate =
7 ???? ????????MAX( 'calendar ' [Date] )
8 ????????VAR StartDate = endDate - 365
9???? ????VAR Result =
10????????????IF(
11 ???? ???????? MAX('calendar ' [Date] ) >= StartMAT,
12 ???? ???? ????CALCULATE(
13 ???? ???????????? [Total sales],
14???????????????? FILTER (
15???? ???????????????? unfilteredCalendar,
16????????????????????'calendar ' [Date] > StartDate
17 ???????????????????? && 'calendar ' [Date] <= endDate
18???????????? )
19 ???????? )
20???? )
21 RETURN
22???? Result
Here are the key points I want you to take away from this latest version of the formula using the VAR syntax:
? Variables make the formula easier to read and understand.
? Good variable names effectively self-document the logic of the formula and make it easier to under-
stand.
? A variable can be assigned a constant (line 3), a table (line 5), or a value that can vary depending on?
the filter context (line 7).
? A variable is reused inside the formula to create other variables (line 8).
從上面使用變量的代碼中,我們不難發(fā)現(xiàn):
??使用變量后,代碼更容易閱讀和理解了。
??變量名稱要易于理解和記憶,理解公式代碼的邏輯更容易。
??變量可以被賦值為一個常量(第3行),一個表(第5行),或者一個可以根據(jù)篩選上下文變化的值(第7行)。
??變量在公式中可以被重復(fù)使用,用于建其他變量(第8行)。
可能有的小伙伴會問,為什么把結(jié)果也寫成一個變量呢?其實這樣做是為了調(diào)試或檢查代碼更方便。我們可以在RETURN后面輸出代碼中的任何一個變量名,看看中間步驟的某個變量返回什么?如果最終步驟結(jié)果不對,就可以通過這種方法逐步排查代碼。這也是使用變量的一大優(yōu)勢。
三、變量對性能的影響 Performance Impacts of Variables
使用變量時,你可能注意不到,或者不很明顯的地方是:它可以提高公式的整體性能。例如,我們再看一下第4章中的[Margin %]度量值,并考慮使用變量和不使用變量的兩個版本的公式。
這是不含變量的版本:Margin % full = DIVIDE([Total Sales] – [Total Cost],[Total Sales])
這是使用變量的版本:
1 ????Margin % Variables =
2 ????????VAR Totalsales = [Total sales]
3 ????????VAR Totalcost = [ Total cost]
4 ????????VAR TotalMargin = Totalsales - TotalCost
5 ????????VAR Result =
6 ???????????? DIVIDE ( TotalMargin,Totalsales )
7 ????RETURN
8 ??????Result
這個公式的第一個版本計算[總銷售額]兩次:一次在分子上(計算利潤率),然后在分母上(計算百分比)。公式的第二個版本只計算[Total Sales]一次,并將其分配給一個變量(第2行)。所以變量可以幫助提高公式的性能。
注:Power BI引擎一直在不斷更新和改進(jìn),開發(fā)人員總是不斷尋找新的方法來提高PBI計算引擎的效率。實際應(yīng)用中你可能覺得變量并沒有發(fā)揮多大作用,因為軟件開發(fā)人員在改進(jìn)引擎方面做的大量優(yōu)化工作部分上抵銷了變量的功勞。即便如此,使用變量來編寫公式仍然是一個很好的習(xí)慣或者說好方法,因為這樣做可以使公式更容易閱讀使用。
四、賦值后的變量是不可變的 Variables Are Immutable
如果你有編程基礎(chǔ)的話,那么你應(yīng)該非常熟悉變量的概念。但DAX中的變量有所不同。DAX中的變量實際上更類似于其他編程語言中的常量,而不是變量。DAX中的變量是不可變的,就是說一旦變量被賦值,那這個值就不再改變。在其它大多數(shù)編程語言中,你可以這樣寫:
X=5
X=X+1
變量X的值可以改變。但是在DAX中這是不可以的,一旦給DAX變量賦予了一個值,那這個值就不能再改變了,直到RETURN返回計算結(jié)果之前。
我們再看一個第9章的例子,度量值是:
Total Sales to Females =
? ? CALCULATE([Total Sales], Customers[Gender] = "F")
假如我們使用變量這樣改造度量值(這是個錯誤的示例,只為演示變量的不可變性)
1 ????Total sales to Females =
2 ????????VAR Totalsales = [Total sales]
3 ????????VAR Result =
4 ???????????? CALCULATE (Totalsales, customers[Gender] = "F")
5 ????RETURN
6 ???????? Result
如果把度量值放在矩陣中,你會發(fā)現(xiàn)并不能得到正確的結(jié)果,就是因為Totalsales被賦予了總銷售額度量值,在關(guān)鍵字RETURN之前,變量的值不可改變,所以Result結(jié)果是錯誤的。我們假設(shè) [Total sales]=10000,相當(dāng)于公式變成了這樣:Result=CALCULATE (10000, customers[Gender] = "F"),這個10000不能被條件篩選了。
我們可以將代碼修改成這樣:
1? ? ?Total sales to Females =
2? ? ?? ? VAR Totalsales = [Total sales]
3? ? ?RETURN
4? ? ?? ? ?CALCULATE (Totalsales, customers[Gender] = "F")
在關(guān)鍵字RETURN之后,就一切正常了。