CALCULATE之庖丁解牛系列 - CALCULATE專解 (9)

?? ?第36式? CALCULATE的元祖--最細(xì)粒度的篩選方式(高級)

? ? ? 請參閱《DAX圣經(jīng)》第5章相關(guān)部分。
? ? ?這部分本來是(8)的后半部分途凫,因?yàn)樘崾咀謹(jǐn)?shù)超過指定數(shù),不得已將其分成了兩部分溢吻。

? ? ? ?在第35式中维费,唯一的問題是:CALCULATE()需要一個返回單個值的表達(dá)式,這一次促王,我們希望返回整個表犀盟。因?yàn)椋覀冃枰斜碜鳛楹Y選函數(shù)的參數(shù)蝇狼。幸運(yùn)的是阅畴,有CALCULATE函數(shù)的一個伙伴可以,它不是返回一個值迅耘,而是返回一個表贱枣。這就是CALCULATETABLE,接下來將介紹颤专。

? ? ? 1纽哥、使用CALCULATETABLE

? ? ? ? CALCULATETABLE的工作方式與CALCULATE相同。唯一的區(qū)別是結(jié)果的類型:CALCULATE計(jì)算返回標(biāo)量值血公,而CALCULATETABLE計(jì)算表表達(dá)式并返回表昵仅。下一個公式完全符合我們的需要:它刪除了品牌和顏色列上的兩個篩選器,而其他列上的篩選器仍保持篩選功能累魔。

[CalcTable Version] :=
CALCULATE(SUM( Sales[SalesAmount] )摔笤,
FILTER(
CALCULATETABLE(Product,ALL( Product[Brand] )垦写,ALL ( Product[Color] ))吕世,AND(Product[Brand] ="TailspinToys",Product[Color] ="Black")))

? ? ? ? 使用CALCULATETABLE計(jì)算出上圖中的正確的值梯投,這個等價(jià)的結(jié)果是很重要的命辖,因?yàn)橹懒苏_的技術(shù):需要將布爾篩選器轉(zhuǎn)換成等效的列表篩選,這將極大地幫助你獲得更復(fù)雜的條件分蓖。例如尔艇,如果想表示OR條件而不是AND條件,那么么鹤,需要采用這種技術(shù)终娃。

? ? ? ?例如,如果要計(jì)算所有brands 和colors--品牌和顏色的總和蒸甜,條件是:該品牌可以是Tailspin Toys棠耕,或者Color-顏色為黑色的(OR條件)余佛,則需要使用CALCULATETABLE來定義它,如下代碼所示:

[CalcTable Version OR]?:=
CALCULATE(SUM( Sales[SalesAmount] )窍荧,
FILTER(
CALCULATETABLE(Product辉巡,
ALL(Product[Brand] ),ALL (Product[Color] ))蕊退,
OR(Product[Brand] ="Tailspin Toys"郊楣,Product[Color] ="Black"))

? ? ? ?實(shí)際上:使用CALCULATETABLE方式可以方便地從Tailspin Toys和Color--品牌和顏色列中去除篩選器,而保持所有其他篩選器不受影響咕痛。
? ? ? ?
一方面痢甘,簡單的使用CALCULATE就可以很容易地解決多列表的條件,因?yàn)橛?b>CALCULATE能將所有的AND篩選器參數(shù)放入其中茉贡。
? ? ? ?另一方面,實(shí)際的使用中者铜,不同列之間的組合條件要復(fù)雜得多腔丧,不能只依賴于AND和CALCULATE,這需要手工編寫復(fù)雜的DAX代碼作烟。值得注意的是愉粤,作為替代公式,還可以使用下面的代碼拿撩,它使用了ALL()函數(shù)直接引用兩個列:

[ALL Version OR]?:=
CALCULATE(SUM( Sales[SalesAmount] )衣厘,
FILTER(ALL ( Product[Brand], Product[Color] )
OR(Product[Brand] ="Tailspin Toys"压恒,Product[Color] ="Black" ) ))

? ? ? 這種形式更優(yōu)雅影暴,即使在開始時(shí),它不是很直觀探赫。你需要慢慢地習(xí)慣它型宙。

? ? ? ?2、CALCULATE的篩選轉(zhuǎn)換

? ? ? ?我們之前曾說到:CALCULATE會執(zhí)行另一項(xiàng)非常重要的任務(wù):CALCULATE將任何現(xiàn)有的行篩選轉(zhuǎn)換為等效的列表篩選伦吠。
? ? ? ?
為了進(jìn)一步再次說明這種行為妆兑,我們創(chuàng)建一個包含CALCULATE表達(dá)式的計(jì)算列。因?yàn)?b>計(jì)算列總是存在行篩選毛仪,因此這將觸發(fā)篩選轉(zhuǎn)換搁嗓。例如,讓我們再次回憶一下相關(guān)的知識點(diǎn):假如在Product表中定義一個計(jì)算列箱靴,其中包含以下DAX表達(dá)式:

? ? ? ?Product[SumOfUnitPrice] =SUM( Product[Unit Price] )

? ? ? ?這個公式你已經(jīng)再熟悉不過:它計(jì)算了所有產(chǎn)品的腺逛、所有價(jià)格的值。表達(dá)式是在隱式行篩選中進(jìn)行計(jì)算的刨晴,沒有顯式列表篩選屉来,因此它返回表中所有產(chǎn)品的總價(jià)路翻,而不是對其進(jìn)行定義的產(chǎn)品列表的每行值的價(jià)格,即返回單位價(jià)格的總金額茄靠。

? ? ? ?現(xiàn)在茂契,我們知道,這需要增加函數(shù)?CALCULATE來顯示化列表處理:

Product[SumOfUnitPriceCalc] =?CALCULATE(SUM( Product[Unit Price] ) )

? ? ? ?我們也許還在驚訝:這是怎么啦慨绳?CALCULATE可以使用一個表達(dá)式參數(shù)計(jì)算掉冶?原因是:使用CALCULATE,行篩選已轉(zhuǎn)換為篩選器篩選脐雪,從而更改了結(jié)果(可以理解為:內(nèi)部引擎以列表形態(tài)一次性計(jì)算出結(jié)果厌小,關(guān)于內(nèi)部引擎的問題,容后再說)战秋。
? ? ? ?當(dāng)?shù)谝淮斡^察到這種行為時(shí)璧亚,你很難理解CALCULATE為什么會執(zhí)行了列表篩選轉(zhuǎn)換。在經(jīng)過這么多的說明后脂信,你將開始使用此功能癣蟋,之后也會慢慢喜歡它,因?yàn)槭褂盟鼘⒛軌蚓帉憦?qiáng)大的公式狰闪。

? ? ? ?此外疯搅,需要提醒的是,篩選的語境轉(zhuǎn)換還有另一個非常重要的副作用埋泵。你可能還記得幔欧,列表篩選和行篩選在關(guān)系方面的行為方式不同:行篩選不會通過關(guān)系自動傳遞,而列表篩選則會在關(guān)系之間傳遞丽声。因此礁蔗,當(dāng)發(fā)生篩選轉(zhuǎn)換時(shí),列表篩選將自動傳遞到相關(guān)的關(guān)系列表恒序,讓我們?nèi)匀辉诋a(chǎn)品表中瘦麸,創(chuàng)建兩個新的計(jì)算列

? ? ? ? Product[SalesAmount] = SUM( Sales[SalesAmount] )? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Product[SalesAmountCalc] = CALCULATE(SUM( Sales[SalesAmount] ) )

? ? ? ?這兩個計(jì)算的結(jié)果顯然是不同的。由CALCULATE定義的篩選轉(zhuǎn)換會影響所有關(guān)系列表的篩選歧胁。[SalesAmount]?列將包含所有銷售的總計(jì)(只有一個值)滋饲,而[Sales AmountCalc]則包含當(dāng)前所有產(chǎn)品行的銷售。這時(shí)喊巍,“CALCULATE() ” 和行篩選在“Product”--產(chǎn)品列上的相關(guān)篩選轉(zhuǎn)換的存在屠缭,將篩選器傳遞到“銷售”表(傳遞的是由CALCULATE()轉(zhuǎn)換后的列表篩選,SUM( Sales[SalesAmount] )的每一次結(jié)果都將被轉(zhuǎn)換為引擎能識別的列表形態(tài))崭参,因而顯示每個產(chǎn)品的銷售情況呵曹。
? ? ? ?請注意,在執(zhí)行CALCULATE()時(shí),所有當(dāng)前活動的行篩選都會發(fā)生篩選轉(zhuǎn)換(每一個行行為都將被轉(zhuǎn)換)奄喂,而且這種行為不能避免(下面將介紹避免的方法)铐殃。實(shí)際上,在不同的表上可能存在一個或多個行篩選跨新。例如富腊,如果在Product表中創(chuàng)建的計(jì)算列中使用AVERAGEX迭代Product--客戶,那么域帐,對于兩個行篩選:Product和Customer都會發(fā)生篩選轉(zhuǎn)換赘被,并且Sales表將同時(shí)接收這兩個篩選器。請考慮以下表達(dá)式:

Product[SalesWithSUMX] =
AVERAGEX(Customer肖揣,CALCULATE(SUM( Sales[SalesAmount] ) ) )

? ? ? ?該公式計(jì)算客戶購買該產(chǎn)品的平均金額(不是指平均價(jià)格民假,而是總支出的平均值)。在一個列表篩選中執(zhí)行SUM計(jì)算:只顯示當(dāng)前客戶的銷售(由AVERAGEX迭代)和當(dāng)前產(chǎn)品的銷售(通過CALCULATE()引用的值列表的列表計(jì)算迭代)龙优。當(dāng)然羊异,公式不能省略CALCUALTE:

Product[SalesWithSUMX] =AVERAGEX(Customer,SUM( Sales[SalesAmount] ) )

? ? ? ?這里有一種簡單的方法來記住這個規(guī)則:在該CALCULATE()中沒有行篩選(或者說只有隱式的行篩選)彤断,只有列表篩選(轉(zhuǎn)換后的顯式列表)存在球化。因?yàn)镈AX公式必須同時(shí)具有值列表(行)篩選與列表篩選。
? ? ? ?或者干脆理解為:CALCULATE()瓦糟,比如CALCULATE(SUM( Sales[SalesAmount] ) ) 是引用一個列表(無論是值列表還是列表,統(tǒng)統(tǒng)視為列表8坝)計(jì)算菩浙,而不是定義一個值列表,也就是說句伶,CALCULATE()是不需要你操心其行行為的劲蜻,因?yàn)橛蠧ALCULATE存在,就有隱式的行行為?加唷)先嬉。

? ? ? ? 更實(shí)際的,你無須理解那么多楚堤,作為一種“投機(jī)取巧”:在你考慮或糾結(jié)是使用CALCULATE(SUM( Sales[SalesAmount] ) ) 以及該形態(tài)的[度量](作為列表被引用)疫蔓,還是使用定義的SUM( Sales[SalesAmount] )時(shí),總使用前者就好身冬!現(xiàn)在衅胀,下面的這兩個公式哪一個是對的?是不是很容易就知道了酥筝?要是以前滚躯,你會很糾結(jié)或者迷茫。雖然我們可以直接給予你答案,但這其中的說明過程很重要掸掏。

Product[SalesWithSUMX] =AVERAGEX(Customer茁影,SUM( Sales[SalesAmount] ) )
Product[SalesWithSUMX] =AVERAGEX(Customer
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? CALCULATE(SUM( Sales[SalesAmount] ) ) )

? ? ? ?注意:為了以示區(qū)別:
? ? ? ?1丧凤、我們通常所指的行篩選是指我們定義的值列表篩選(顯式行篩選)募闲,列表篩選為引用的列表(顯式列表篩選),而那些不需要我們操心(定義或引用)引擎能自動完成的行為(無論行行為還是列表行為)都稱為隱式的行行為或列表行為(隱式行篩選和隱式列表篩選)息裸;
? ? ? ?2蝇更、我們將非隱式篩選器稱為顯式篩選器,或者直接稱為:常規(guī)篩選器呼盆。這樣做的唯一目的是在需要時(shí)能區(qū)分顯式篩選和隱式篩選年扩,以掌握它們的不同之處。雖然通常情況下访圃,是不需要考慮隱式的行為的(那是內(nèi)部引擎的事情)厨幻。
? ? ? ?但在解釋某些更復(fù)雜的DAX行為,以及運(yùn)用這些行為書寫DAX解決一些復(fù)雜的業(yè)務(wù)邏輯時(shí)卻相當(dāng)有用腿时。比如接下來的以ALLSELECTED函數(shù)開始的終極列表篩選問題况脆,如果不理解或不接受隱式和顯式的概念,將很艱難批糟。

? ? ? ? 在最新的SQLBI關(guān)于ALLSELECTED的博文介紹中格了,意大利的大師主動就這個問題道歉:為在《DAX圣經(jīng)》中關(guān)于ALLSELECTED函數(shù)講解中的某些不適當(dāng)(錯誤)定義。并首次提出隱式行篩選的問題徽鼎。(當(dāng)時(shí)化了整整幾十頁的說明文字也沒有說清楚盛末,應(yīng)為沒有引入隱式的概念。)

? ? ? ?大致的意思是:如果您已閱讀第一版“DAX權(quán)威指南”否淤,請將本文內(nèi)容作為對該書的錯誤評論的修正悄但。 事實(shí)上,我們在這里的表述將比在寫那本書時(shí)更精確和清晰石抡。 我們?yōu)榇说狼浮? ? ??

? ? ?3檐嚣、度量里的篩選轉(zhuǎn)換

? ? ? 關(guān)于隱式篩選的問題,很多人對我提出該說法有不同的想法啰扛,或者說我曲解了意大利人的隱式定義嚎京。我很理解。如果你堅(jiān)持看完我的系列啰嗦侠讯,最后我們將以相當(dāng)多的案例篇幅來說明這個問題挖藏,現(xiàn)在還不是爭論的時(shí)候。這也說明篩選轉(zhuǎn)換在DAX里的重要性厢漩。
?
? ? ? ?我們說膜眠,理解篩選轉(zhuǎn)換非常重要,因?yàn)檫@是DAX的另一個隱式的方面。到目前為止宵膨,我們一直在CALCULATE中使用函數(shù)引用列或定義值列表來編寫表達(dá)式架谎。但是,你還可以編寫包含度量值調(diào)用的表達(dá)式辟躏。如果從計(jì)算列中調(diào)用度量值谷扣,會發(fā)生什么情況?
? ? ? ?后者為更普遍的情況捎琐。例如会涎,可以定義一個SumOfSalesAmount度量:

? ? ? ? [SumOfSalesAmount] :=SUM( Sales[SalesAmount] )

? ? ? ?然后,可以使用這個更簡單的代碼定義SalesWithSUMX計(jì)算列:

? ? ? ?Product[SalesWithSUMX] =SUMX(Customer瑞凑,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? CALCULATE([SumOfSalesAmount]))??

? ? ? ?CALCULATE的存在意味著執(zhí)行了篩選轉(zhuǎn)換末秃。問題是,每當(dāng)從另一個表達(dá)式中調(diào)用度量值時(shí)籽御,DAX將自動調(diào)用CALCULATE封裝內(nèi)部的度量练慕。也就是說:任何一個度量被引用時(shí),都可以看作是一個省略了CALCULATE()的顯式列表技掏。換句話說:任何一個度量都可以作為顯式化的列表被引用铃将。因此,前面的表達(dá)式具有與以下表達(dá)式相同的行為:

? ? ? ?Product[SalesWithSUMX]=SUMX(Customer哑梳, [SumOfSalesAmount])

? ? ? ?這一次劲阎,在公式中看不到CALCULATE,但是由于DAX添加CALCULATE自動計(jì)算鸠真,所以會發(fā)生篩選轉(zhuǎn)換哪工。這就是為什么總是編寫DAX時(shí)需要區(qū)分列和度量的代碼是非常重要的原因。寫DAX使用的事實(shí)上的標(biāo)準(zhǔn)是:

? ? ? ?避免將表名放在度量之前弧哎,并且總是在列前面加上表名。

? ? ? ? 事實(shí)上稚虎,在以前的公式里撤嫩,例如[SumOfSalesAMounp]之前沒有表名,這表明它是一個度量蠢终,因此序攘,知道發(fā)生了篩選轉(zhuǎn)變。

? ? ? 自動篩選轉(zhuǎn)換使編寫使用迭代來執(zhí)行復(fù)雜計(jì)算的公式變得非常容易寻拂。話雖如此程奠,我們需要一段時(shí)間才能熟悉閱讀和使用它。例如祭钉,如果只想計(jì)算購買量超過總平均值的客戶的銷售額之和瞄沙,可以編寫如下度量:

[SalesMoreThanAverage]?=
VAR AverageSales = AVERAGEX( Customer,[SumOfSalesAmount]?)
RETURN
SUMX(Customer,
IF([SumOfSalesAmount]?> AverageSales距境,[SumOfSalesAmount]))

? ? ? ?在這個代碼中申尼,我們使用[SumOfSalesAmount]作度量為不同行篩選中。在VAR定義的變量中垫桂,使用它來計(jì)算客戶銷售的平均值师幕,而在使用SUMX的迭代中,我們使用它來檢查當(dāng)前客戶的銷售額與先前存儲在變量中的平均值作比較诬滩。
? ? ? ?基于VAR的語法更易于讀取和維護(hù)(也可能更快)霹粥。但是,重要的是要理解針對不同行為來使用不同的語法疼鸟,不管使用的DAX版本如何后控,如果不理解并掌握自動篩選轉(zhuǎn)換,就沒有完全了解CALCULATE愚臀。那么忆蚀,可能會花費(fèi)大量的時(shí)間來查看公式。這與使用VAR無關(guān)姑裂。

?? ? ? 在引用度量值時(shí)馋袜,篩選轉(zhuǎn)換總會自動發(fā)生,而且無法避免舶斧。這意味著在調(diào)用度量值時(shí)需要避免篩選轉(zhuǎn)換時(shí)欣鳖,唯一方法是擴(kuò)展其代碼。例如茴厉,假設(shè)以不同的方式編寫了前面的代碼泽台。而不是使用VAR變量,定義一個名為[AverageSales]的度量矾缓,它表示客戶的平均銷售額怀酷,如下所示:

[AverageSales]?:? ? ? ? ? ? ??= AVERAGEX( Customer,[SumOfSalesAmount] )[SalesMoreThanAverage]:= SUMX(Customer嗜闻,
IF( [SumOfSalesAmount] > [AverageSales]蜕依,[SumOfSalesAmount]))

? ? ? ?在突出顯示的行中,使用[AverageSales]計(jì)算客戶的平均銷售額琉雳。問題是--這一次--在(SUMX)迭代中調(diào)用了一個度量样眠,這會發(fā)生篩選轉(zhuǎn)換。因此翠肘,[AverageSales]的結(jié)果將不是針對所有客戶的平均銷售檐束,而是正在迭代的客戶的平均銷售額。因此束倍,測試失敗被丧,度量返回空白盟戏。

? ? ? ? 最簡單的理解:度量一旦被引用,總是以一個顯式列表狀態(tài)在晚碾,?[SumOfSalesAmount] > [AverageSales]相當(dāng)于“列表=列表”抓半,這是不允許的,或者說都是全集的列表與列表間的比較格嘁,毫無意義笛求。這里表現(xiàn)為:IF的真正條件并沒有執(zhí)行或不起作用。

? ? ? ?如果要避免這種篩選轉(zhuǎn)換糕簿,則需要擴(kuò)展度量的代碼(即函數(shù)定義的值列表)探入,也就是前面所說的“列表=值列表”的方式。如以下示例所示:

[SalesMoreThanAverage] :=
SUMX(Customer懂诗,
IF([SumOfSalesAmount]>AVERAGEX( Customer蜂嗽,
[SumOfSalesAmount]),[SumOfSalesAmount]))

? ? ?將單獨(dú)的度量引用替換為擴(kuò)展代碼方式(即函數(shù)定義的計(jì)算式)后殃恒,[SalesMoreThanAverage]將返回正確的結(jié)果植旧。
? ? ? ?我們發(fā)現(xiàn),如果按照DAX的原理來理解這些公式會比較難于理解离唐,我們的目的是運(yùn)用病附,因而借用“引用列表”與“定義值列表”的概念則相當(dāng)容易,你只需要知道何時(shí)使用它們以及在什么情況下使用它們亥鬓。

? ? ? ?此外完沪,值得注意的是,公式在Customer表上有兩個嵌套的行篩選和三個度量調(diào)用嵌戈。其中兩個通過SUMX計(jì)算當(dāng)前迭代客戶的銷售額覆积,另一個(在AVERAGEX內(nèi)部)通過AVERAGEX計(jì)算當(dāng)前迭代客戶的銷售。整個IF函數(shù)是一個布爾值列表熟呛,用以作為SUMX遍歷Customer表的計(jì)算條件宽档。

? ? ? 上面圖示中的兩個行行為,是“X”類聚合函數(shù)的對第一參數(shù)--表的所謂“遍歷表”功能庵朝,Customer表分別被兩個函數(shù)引用(被遍歷了兩次).

? ? ? ?我們將在接下來的內(nèi)容中廣泛使用這些特性雌贱,屆時(shí)我們將開始編寫復(fù)雜的DAX代碼來解決特定的場景。在接下來的一式中偿短,可能會更利于理解。

? ? 第37式?CALCULATE的篩選轉(zhuǎn)換(加強(qiáng))?

? ? ? 1馋没、篩選轉(zhuǎn)換后的當(dāng)前列值是多少昔逗?

篩選轉(zhuǎn)換將行篩選轉(zhuǎn)換為等效的列表篩選。這一說法需要作出一些澄清:
? ? ? ?一方面篷朵,行篩選始終只包含一行婆排,而CALCULATE在篩選轉(zhuǎn)換后創(chuàng)建的列表篩選則可能包含多個行:
? ? ? ?另一方面,由CALCULATE創(chuàng)建的篩選器可能會影響一個或多個列笔链,這取決于列表結(jié)構(gòu)(關(guān)系)段只。

? ? ? 1)如果表中有一個在模型里被定義的主鍵,那么鉴扫,CALCULATE將創(chuàng)建一個列表篩選赞枕,并只篩選該主鍵。事實(shí)上坪创,這樣的列表篩選包含一個行炕婶,它由主鍵唯一標(biāo)識。值得記住的是:可以通過使用現(xiàn)有表的元數(shù)據(jù)或創(chuàng)建列表之間的關(guān)系來定義主鍵莱预。
? ? ? ?在這兩種情況下柠掂,篩選轉(zhuǎn)換都將篩選單個的列,而且由于該列是表的標(biāo)識主鍵列依沮,因此將篩選主鍵唯一行對應(yīng)的單個行涯贞。
? ? ? ?2)如果表沒有主鍵,則篩選轉(zhuǎn)換將在表的所有列上創(chuàng)建一個篩選器危喉。它可能導(dǎo)致包含一行或多行的篩選器宋渔,這取決于列表的內(nèi)容。
? ? ? ?實(shí)際上姥饰,如果所有的行都不同傻谁,那么,篩選器篩選將唯一地標(biāo)識一行列粪。但是审磁,如果表中有相同的行,那么岂座,所有行都將包含在該列表篩選中态蒂。在前面已提示的以下示例中,[Wrong Sales]和[Correct Sales]會導(dǎo)致返回不同的值:

[Sales Amount] := SUMX( Sales费什,Sales[Quantity] * Sales[Unit Price] )
[Wrong Sales]:? ?= SUMX( Sales钾恢,[Sales Amount] )
[Correct Sales]:? = SUMX( Sales,Sales[Quantity] * Sales[Unit Price] )

? ? ? 事實(shí)上鸳址,[Wrong Sales]會迭代Sales--銷售表瘩蚪,對于每一行,它計(jì)算所有相同行的[SalesAmount] --[銷售金額](即每個唯一值的行的計(jì)算)稿黍,而[Correct Sales]則計(jì)算每一行(不考慮是否重復(fù))的金額疹瘦。因此,如果銷售中有多個相同(重復(fù)的行)的行巡球,則[Wrong Sales]會導(dǎo)致得出更高的值言沐。

? ? ? ?在處理維度表時(shí)邓嘹,這通常不是問題,因?yàn)榫S度表總是存在唯一值的主鍵险胰。在這種情況下汹押,與當(dāng)前行相同的每個唯一行是該行本身。那么起便,關(guān)于事實(shí)表或其他用于計(jì)算的表呢棚贾?……。一般情況下缨睡,對于那些沒有主鍵的表(通常是事實(shí)表或用于計(jì)算的表)鸟悴,都需要考慮可能有重復(fù)的行(事實(shí)上也總是如此),否則可能會得到意想不到的結(jié)果奖年。

? ? ? 2细诸、理解篩選轉(zhuǎn)換的計(jì)算順序

? ? ? ?根據(jù)你已學(xué)習(xí)到的經(jīng)驗(yàn),了解了在Product--產(chǎn)品表中創(chuàng)建的這兩個計(jì)算列之間的區(qū)別:

Product[SumOfUnitPrice]? ? ? ? ? ? ? ? = CALCULATE(SUM( Product[Unit Price]))Product[SumOfAllUnitPrice] = CALCULATE(SUM( Product[Unit Price] )陋守,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ALL ( Product ) )

? ? ? ?它們都是計(jì)算列震贵,都使用CALCULATE函數(shù)功能。因此水评,兩種情況都會發(fā)生篩選轉(zhuǎn)換猩系。第一個[SumOfUnitPrice]應(yīng)該只包含當(dāng)前行的[Unit Price]-單位價(jià)格的值。
? ? ? ?但是中燥,[SumOfAllUnitPrice]的值是什么寇甸?直觀地,因?yàn)橛幸粋€? ALL(Product)疗涉,期望它應(yīng)該包含所有[Unit Price]-單位價(jià)格列的總和拿霉,這也正是它所計(jì)算的。然而咱扣,如果遵守到目前為止我們已知的所有規(guī)則绽淘,就會發(fā)現(xiàn)這里總有些不對勁。

? ? ? ?因?yàn)锳LL(Product)的結(jié)果返回整個Product表闹伪,這有效地從篩選器篩選中刪除了任何篩選器沪铭。但同時(shí),由于篩選轉(zhuǎn)換偏瓤,應(yīng)該篩選Product表杀怠,并只使一行可見。如果將這兩個條件AND在一起厅克,篩選轉(zhuǎn)換就會有更多的限制赔退,因此,它應(yīng)該會起作用已骇。那么离钝,為什么結(jié)果總是所有單價(jià)的總和,而不是當(dāng)前行的單價(jià)褪储?

? ? ? ?這是因?yàn)槁芽剩Y選轉(zhuǎn)換創(chuàng)建的列表篩選與CALCULATE()的條件創(chuàng)建的篩選篩選之間具有優(yōu)先順序。CALCULATE會先執(zhí)行篩選轉(zhuǎn)換鲤竹,然后應(yīng)用篩選器浪读。因此:

? ? ? ?CALCULATE的任何條件都可以覆蓋篩選轉(zhuǎn)換創(chuàng)建的篩選器。

? ? ? ?這種行為描述它要比使用它更難辛藻。上面的兩個公式精確地計(jì)算了我們在直覺上所期望的結(jié)果碘橘。然而,重要的是要理解為什么會發(fā)生這種情況吱肌,更最要的是痘拆,被CALCULATE()覆蓋的篩選器來自篩選轉(zhuǎn)換(換句話說,篩選器參數(shù)稍后才被應(yīng)用)氮墨。

? ? ? 上述公式中纺蛆,由于ALL ( Product ) 的結(jié)果是一個全集的列表,因而篩選并不會起作用(結(jié)果與第一個類似公式相同)规揪。但是桥氏,如果是ALL ( Product [某列]) ,結(jié)果將是一個唯一值的結(jié)果表(值列表)猛铅,篩選將會起到作用字支。這是我們第二次提高這個區(qū)別。

? ? ? 3奸忽、定義變量與定義篩選
? ? ? 在變量系列中堕伪,我們展示了變量的概念,這個概念是通過使用如下表達(dá)式創(chuàng)建的:

VAR Denominator = SUMX( Sales月杉,Sales[Line Amount] - Sales[Line Cost])
VAR Numerator? ? ?= SUM (Sales[Line Amount])
RETURN
DIVIDE(Numerator , Denominator )

? ? ? ?VAR變量可以使代碼更方便刃跛、更容易閱讀,并避免重復(fù)相同的子表達(dá)式苛萎,而且,由于它們對應(yīng)于處理計(jì)算篩選的方式桨昙,它們還有另一個非常重要的用途。
? ? ? ? 實(shí)際上:VAR變量是在 DAX定義的當(dāng)前篩選中被計(jì)算腌歉,而不是在創(chuàng)建它們的公當(dāng)前式中計(jì)算蛙酪。即必須 RETURN “取出來”使用。
? ? ? ?
這個特性對于創(chuàng)建復(fù)雜的公式非常有用翘盖。在這些公式中桂塞,可以引用基于“以前”存在的計(jì)算篩選的值。讓我們用一個例子來說明馍驯。想象一下阁危,我們想要使用一個透視表來顯示類別玛痊,以及每個類別中的銷量高的產(chǎn)品數(shù)量。定義該類產(chǎn)品的條件:如果它的銷售額超過了這個類別總銷售額的10%狂打,那就算是高銷量了擂煞。

? ? ? ?這很容易用變量來計(jì)算。此外趴乡,使用變量處理會使閱讀變得更簡單对省,正如在以下代碼中所看到的那樣:

[HighSalesProducts] :=
VAR TenPercentOfSales =[SalesAmount] * 0.1
RETURN
COUNTROWS ( FILTER ( Product,[SalesAmount]>=TenPercentOfSales)

? ? ? ?這個公式有趣的部分是DAX在篩選器迭代之外計(jì)算變量[TenPercentOfSales]晾捏。如果[TenPercentOfSales]的計(jì)算在篩選器迭代中蒿涎,它將計(jì)算當(dāng)前迭代產(chǎn)品由于篩選轉(zhuǎn)換而計(jì)算銷售額的10%悠反,這將使整個度量無法計(jì)算其值溃斋。

? ? ? ?相反,DAX先計(jì)算迭代外部的值攻礼,然后在內(nèi)部使用它裙品,從而可以引用當(dāng)前篩選器篩選之外的表達(dá)式的值俗批。這相當(dāng)于事先定義了一個值列表,然后再引用它作為參數(shù)計(jì)算(這里是做為布爾值篩選的“列表”="值列表"中的值列表市怎,即通常所說的“當(dāng)前行”)如果要編寫沒有變量的相同方式的度量岁忘,則應(yīng)該編寫如下表達(dá)式:

[HighSalesProductsCalculate] :=
COUNTROWS ( FILTER(Product,
[SalesAmount] >=?CALCULATE( [SalesAmount]区匠,
ALL(Product)干像,'ProductCategory') *0.1)
)

? ? ? 最后這一段代碼很難閱讀,基本上驰弄,需要在迭代中重建之前的CALCULATE篩選麻汰,這并不是一項(xiàng)容易的任務(wù),即使對于經(jīng)驗(yàn)豐富的DAX程序員來說也是如此戚篙。實(shí)際上五鲫,這將只在后面的最后關(guān)于列表篩選的定義時(shí),了解到前面表達(dá)式的細(xì)節(jié)岔擂,我們將最后一次揭示篩選器篩選的所有細(xì)節(jié)位喂。

? ? ? 如果在閱讀前面的示例時(shí),你發(fā)現(xiàn)可以使用變量來計(jì)算一些內(nèi)容乱灵,比如替代EARLIER(當(dāng)前行)的篩選計(jì)算塑崖,那么,我們可以很高興地稱呼你為DAX精英痛倚,因?yàn)槟惴浅A私釪AX的計(jì)算+篩選规婆。如果還沒有達(dá)到這一步,也不要擔(dān)心。

? ? ? 不可能一開始第一次閱讀就能掌握抒蚜,仍然有很多內(nèi)容專門討論這些復(fù)雜的主題掘鄙,這將幫助我們獲得掌握計(jì)算+篩選所需的技能。

? ? 第37式??CALCULATE 列表關(guān)系的循環(huán)依賴

? ? ? ?在設(shè)計(jì)數(shù)據(jù)模型時(shí)嗡髓,應(yīng)該注意一個較為復(fù)雜的主題通铲,即公式中的循環(huán)依賴關(guān)系。雖然我們盡量避免討論較為復(fù)雜的DAX問題器贩,但簡單的了解模型中的列表關(guān)系間的循環(huán)依賴是什么,以及如何在模型中避免循環(huán)依賴朋截,很有必要蛹稍。事實(shí)上,實(shí)際運(yùn)用中經(jīng)常會遇到這些問題部服。

? ? ? ?在討論循環(huán)依賴關(guān)系之前唆姐,值得討論的是簡單的線性依賴關(guān)系。讓我們先觀察一個具有以下計(jì)算列的示例:

? ? ? ?Product[Profit] =?Product[Unit Price] - Product[Unit Cost]

? ? ? ?該計(jì)算列依賴于同一Product表的兩列:[Unit Price]列與[Unit Cost]列廓八。在這種情況下奉芦,我們說:[Profit]利潤列取決于[Unit Price]和[Unit Cost]--單價(jià)列以及單位成本列。然后剧蹂,可以創(chuàng)建一個新列声功,類似于具有以下公式的[profitPct]:

? ? ? ? Product[ProfitPct] = Product[Profit] / Product[Unit Price]

? ? ? 顯然,同樣[ProfitPct]--利潤宠叼,又依賴于[Profit]和[Unit Price]--利潤和價(jià)格兩列先巴。因此,當(dāng)DAX計(jì)算出Product表中的計(jì)算列時(shí)冒冬,它會識別出伸蚯,并只在[Profit]之后計(jì)算[ProfitPct]。否則简烤,它將無法計(jì)算ProfitPct公式的有效值剂邮。這是列表產(chǎn)生的順序,也就是你引用的列表必須事先存在横侦。
? ? ? ?循環(huán)依賴通常不需要過于去擔(dān)心它挥萌。在DAX內(nèi)部使用它,可用來檢測計(jì)算結(jié)果的正確順序丈咐。

? ? ? 在具有多個計(jì)算列的普通數(shù)據(jù)模型中瑞眼,計(jì)算的依賴關(guān)系變成了一個復(fù)雜的形狀,但同樣棵逊,引擎的處理卻任然很優(yōu)雅伤疙。
? ? ? ?循環(huán)依賴關(guān)系是在列表出現(xiàn)循環(huán)時(shí)發(fā)生的情況。例如,出現(xiàn)循環(huán)依賴的一個明顯情況是徒像,如果試圖將Profit利潤的定義修改為此公式:

? ? ? ? Product[Profit] : = Product[ProfitPct] * Product[Unit Price]

? ? ? ?因?yàn)閇Profit]依賴于[ProfitPct]產(chǎn)生黍特,而在這個新的公式中,[Profit]又取決于[ProfitPct]锯蛀,從順序上來說灭衷,該公式引用[ProfitPct]后又回到[ProfitPct],形成一個[ProfitPct]列表閉環(huán)旁涤。從列表篩選的本質(zhì)上看翔曲,引用某個列表然后其結(jié)果又重新回到該列表(相當(dāng)于列表沒有任何變化,開始與結(jié)果都是全集的列表狀態(tài)劈愚,這將沒有實(shí)際意義)瞳遍。

? ? ? ?當(dāng)然,引用某個列表全集作為某個函數(shù)的參數(shù)菌羽,或參與其他方式的計(jì)算都是可以的掠械。但單獨(dú)引用某個列表,然后兜一圈回來注祖,結(jié)果又回到該列表猾蒂,這就有點(diǎn)玩弄DAX引擎了。所以是晨,DAX很聰明的拒絕執(zhí)行公式肚菠,并顯示錯誤“檢測到循環(huán)依賴”。
? ? ? ?到目前為止罩缴,我們已經(jīng)從公式的角度了解了循環(huán)依賴項(xiàng)是什么:也就是說案糙,通過查看表達(dá)式,無須關(guān)注表內(nèi)容靴庆,你已能檢測出依賴性的存在时捌。

? ? ? ?然而,還存在更加微妙和復(fù)雜的依賴類型炉抒,例如奢讨,通過使用CALCULATE()或任何表達(dá)式內(nèi)部的篩選器引發(fā)的循環(huán)依賴。
? ? ? ?讓我們用一個示例演示這個場景焰薄,從Product表的一個列表子集(值列表)開始拿诸,如圖5-18所示。請注意塞茅,對于這個例子亩码,我們只加載了Product表,從模型中刪除了所有其他列表野瘦,以便使場景更加明顯描沟。

? ? ? 我們有興趣理解使用CALCULATE函數(shù)的新計(jì)算列的依賴項(xiàng)列表飒泻,如下所示:

? ? ? ?Product[SumOfUnitPrice] = CALCULATE(SUM(Product[Unit Price] ) )

? ? ? 乍一看,該列似乎僅依賴于[Unit Price]列吏廉,因?yàn)檫@是公式中引用的唯一列泞遗。然而,我們使用CALCULATE將當(dāng)前行篩選轉(zhuǎn)換為了篩選器篩選席覆。因?yàn)槲覀儧]有定義與表的任何關(guān)系史辙,也沒有為它設(shè)置主鍵。所以佩伤,當(dāng)CALCULATE進(jìn)行篩選轉(zhuǎn)換時(shí)聊倔,它會篩選表的所有列。
? ? ? ?如果我們擴(kuò)展CALCULATE調(diào)用的含義生巡,公式實(shí)際上是Product表中的ProductKey方库、ProductName、UnitCost以及UnitPrice所有這些列中具有相同值的所有行的[value of Unit Price]--單位價(jià)格值之和障斋。

? ? ? 如果以這種方式讀取公式,那么徐鹤,現(xiàn)在可以清楚地看到:代碼依賴于Products表的所有列垃环,因?yàn)樾乱氲牧斜砗Y選將篩選表中的所有列》稻矗可以在下圖中看到結(jié)果表遂庄。

? ? ? ?你可以看到[SumOfUnitPrice]的Product表的計(jì)算列【⒃可以嘗試在同一個表中使用完全相同的公式定義一個新的計(jì)算列涛目。考慮使用以下公式定義NewSumOfUnitPrice凛澎,該公式與前一個公式完全相同霹肝。

? ? ? ? Product[NewSumOfUnitPrice] = CALCULATE(SUM(Product[Unit Price] ) )

? ? ? 令人驚訝的是,此時(shí)DAX會引發(fā)一個錯誤:檢測到了循環(huán)依賴關(guān)系塑煎。這很奇怪沫换,因?yàn)槲覀冞@時(shí)候使用的實(shí)際是相同的代碼,公式檢測到了以前沒有檢測到的循環(huán)依賴關(guān)系最铁。這里確實(shí)發(fā)生了一些變化讯赏,這是表中列的數(shù)量。如果能夠?qū)ewSumOfUnitPrice添加到表中冷尉,我們就會達(dá)到這樣的情況:
? ? ? ?這兩個公式具有以下含義:[SUMOfUnitPrice]求Product表中與ProductKey漱挎、ProductName、Unit Cost以及UnitPrice和NewSumOfUnitPrice中具有相同值的雀哨、所有行的磕谅、UnitPrice--單位價(jià)格值。

? ? ? [NewSumOfUnitPrice]對Product表中與ProductKey、ProductName怜庸、Unit Cost和UnitPrice以及SumOfUnitPrice的所有行的Unit Price--單位價(jià)格值当犯。

? ? ? ?計(jì)算列與表中的任何其他列一樣,成為CALCULATE引入的篩選器篩選的一部分割疾。因此嚎卫,所有計(jì)算列都是依賴項(xiàng)--列表的一部分。

如果閱讀了前面的定義宏榕,很明顯拓诸,這兩個公式之間存在一個循環(huán)依賴關(guān)系:即NewSumOfUnitPrice與SumOfUnitPrice的互為引用。這就是DAX拒絕創(chuàng)建NewSumOfUnitPrice的原因麻昼。理解這個錯誤并不容易奠支。然而,找到一個解決方案卻很簡單抚芦,即使不是很直觀倍谜。問題是:

? ? ? ?一方面,如果表沒有主鍵叉抡,那么任何包含CALCULATE的計(jì)算列(或調(diào)用任何度量尔崔,都會添加自動CALCULATE()顯式列表篩選),即從表的所有列(包括計(jì)算列)創(chuàng)建依賴項(xiàng)褥民。
? ? ? ?另一方面季春,如果表有一個行標(biāo)識符(按數(shù)據(jù)庫術(shù)語來說,是主鍵)消返,則情況就不同了:當(dāng)表中有一個列充當(dāng)行標(biāo)識符時(shí)载弄,所有包含CALCULATE函數(shù)的列都將依賴于該行標(biāo)識符所在列,從而將它們的依賴項(xiàng)列表縮減為該單個列(主鍵列)撵颊。
? ? ? ?在ProductKey列中宇攻,ProductKey列可以唯一地標(biāo)識到表的每一行,因?yàn)樗侵麈I倡勇。為了將Productkey標(biāo)記為行標(biāo)識符尺碰,有兩個選項(xiàng):

? ? ? 1)使用ProductKey作為目標(biāo)列,從任何表創(chuàng)建關(guān)系译隘。執(zhí)行此操作的前提是:確保[ProductKey]列是產(chǎn)品的唯一值亲桥;
? ? ? ?2) 可以手動設(shè)置[ProductKey]列的行標(biāo)識符的列表 “表行為”屬性。

? ? ? ?行標(biāo)識符并不總是單指某一列(某一個字段屬性)得到行固耘,有可能為多個甚至需要整個表的列表屬性來標(biāo)示為行標(biāo)識符题篷。這是我們前面提到的數(shù)據(jù)模型表的行的概念(數(shù)據(jù)模型表中橫向一列或多列所在的行)。這是DAX列表關(guān)系靈活的地方厅目。

? ? ? ?這其中任何一個操作都能告訴DAX引擎:該表有一個行標(biāo)識符番枚。在這種情況下法严,現(xiàn)在,你可以定義[NewSumOfUnitPrice]列來避免循環(huán)依賴關(guān)系葫笼,因?yàn)椋?b>使用CALCULATE的計(jì)算列僅依賴于新的鍵--行標(biāo)識符深啤。

? ? ? ?無論哪一種篩選,都需要關(guān)系的標(biāo)識符路星。其實(shí)就是列表先必須具有關(guān)系溯街,這是前提。我們把前面那句話再次補(bǔ)充一遍:

? ? ? ?任何添加到數(shù)據(jù)模型中的計(jì)算列都成為由CALCULATE引入的篩選器的一部分洋丐,而且結(jié)果是所有計(jì)算列都成為依賴列表的一部分呈昔。閱讀上述定義,兩個公式之間很明確地存在著循環(huán)依賴友绝,這恰恰就是DAX拒絕創(chuàng)建NewSumOfListPrice列的原因堤尾。

? ? ? ?要理解該錯誤并不容易,但是迁客,找到解決方案卻相當(dāng)簡單郭宝。問題在于任何包含CALCULATE的計(jì)算列(或?qū)θ魏味攘康恼{(diào)用,這些調(diào)用都添加了一個自動的CALCULATE)掷漱,即創(chuàng)建了對表格中所有列的依賴粘室。如果表中有一個行標(biāo)識符(用數(shù)據(jù)庫術(shù)語來說是主鍵),情況將會有所不同切威。如果表中有某個作為行標(biāo)識符的列,那么丙号,包含CALCULATE()的所有列可僅依賴該行標(biāo)識符先朦,從而降低對某個列的列表依賴。

? ? 第38式??CALCULTE 規(guī)則 (列表行為方式)

? ? ? ?重述CALCULATE工作的方式是很有用的犬缨≡海可以使用這組規(guī)則來測試DAX的計(jì)算知識:如果能夠閱讀和理解所有這些規(guī)則,那么怀薛,就可能會成為真正的DAX大師了刺彩。

? ? ? ?1、CALCULATE和 CALCULATETABLE是DAX中唯一能直接操作篩選器篩選(行枝恋、列篩選)的函數(shù)创倔;
? ? ? ?有人說,F(xiàn)ILTER才是列表篩選焚碌,這是兩個概念畦攘,嚴(yán)格的說:FILTER只是CALCULATE的列表參數(shù),或者是組合列表(提供CALCULATE篩選參數(shù)的依據(jù)十电、邏輯條件知押,其實(shí)際是為CALCULATE提供FILTER的兩大功能:值列表狀態(tài)與列表行為)叹螟;

? ? ? ? 2、CALCULATE()只有一個必需的參數(shù)台盯,即需要計(jì)算的表達(dá)式罢绽。其他參數(shù)(也稱為篩選參數(shù)),它們是(一組)篩選器静盅,它將用于構(gòu)建新的篩選器篩選:如果只是需要調(diào)用CALCULATE來執(zhí)行篩選轉(zhuǎn)換良价,則可以省略它們。
? ?
? ? 3温亲、CALCULATE中的篩選器(值列表)參數(shù)定義可以有三種形狀:
? ? ? ??1)布爾條件棚壁,也叫布爾值列表。如Product[Color] = “White”栈虚;
? ? ? ? 2)某一列表的值列表袖外。形式為單列表,如:
? ? ? ALL(Product[Color])魂务;
? ? ? VALUES(Product[Color]) 等曼验。
?或具有更復(fù)雜的表函數(shù)--如FILTER 表達(dá)式,例如:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?FILTER(ALL(Product[Color]粘姜,Product[Color]?= “White” )鬓照。這里可以看出來,F(xiàn)ILTER()的結(jié)果是一個值列表孤紧。
? ? ? ?3)某個表(多個列表)的值列表豺裆,如ALL(Product)或更復(fù)雜的FILTER條件,如? ? ? ? FILTER(ALL(Product)号显,Product[Color]= “White”臭猜。由于FILTER引用的是ALL(Product)(Product表的全部列表),其結(jié)果也將是Product表的全部這些列表的列表子集押蚤。

? ? ? ?使用 1)或 2)的形態(tài)寫的條件只能在一列上運(yùn)行蔑歌。使用 3)形態(tài)編寫的條件可以在任意數(shù)量的列上工作。
? ? ? ?CALCULATE中的所有篩選器參數(shù)都是獨(dú)立(單線程)計(jì)算的揽碘,然后將這些篩選及邏輯條件集聚在一起次屠。最后用于確定新創(chuàng)建的篩選器篩選。
? ? ? ?CALCULATE的篩選器參數(shù)(從第二個參數(shù)開始)都是在原始的列表篩選中計(jì)算的雳刺,它們可以縮小劫灶、擴(kuò)展或替換計(jì)算列表的范圍。

? ? ? ?其實(shí)掖桦,更好浑此、更易于理解的表述:所謂縮小、擴(kuò)展或替換等說話滞详,統(tǒng)一為“當(dāng)前列表”或產(chǎn)生了新的列表集凛俱。
? ? ? ?例如紊馏,當(dāng)使用直接布爾表達(dá)式作為參數(shù)時(shí),CALCULATE將替換原始篩選器篩選蒲犬,而當(dāng)傳遞一個在表上使用篩選器的表達(dá)式時(shí)朱监,CALCULATE會考慮原始篩選篩選。CALCULATE的第一個參數(shù)(要計(jì)算的表達(dá)式)是在新創(chuàng)建的篩選器篩選后的結(jié)果中計(jì)算的原叮。

? ? ? ? 而且赫编,我們再次提示:在CALCULATE的篩選轉(zhuǎn)換以及篩選參數(shù)之間存在優(yōu)先順序。即? CALCULATE在執(zhí)行篩選轉(zhuǎn)換之后應(yīng)用篩選器奋隶。因此擂送,篩選器可以覆蓋轉(zhuǎn)換已創(chuàng)建的篩選。

? ? ?第39式??CALCULATE 的列表篩選(高級)

? ? ? ? 在前面唯欣,我們介紹了列表篩選嘹吨,知道如何引用列表與定義值列表創(chuàng)建DAX的篩選計(jì)算。到目前為止境氢,你已經(jīng)學(xué)會了如何使用它們來定義一些簡單的計(jì)算公式蟀拷。
? ? ? 然而,前面所有關(guān)于“當(dāng)前列表篩選”的定義都是不完整的萍聊,或者更確切地說问芬,只是當(dāng)前列表篩選最初的大概意思。
? ? ? ?為了能繼續(xù)進(jìn)行更復(fù)雜的計(jì)算寿桨,并充分了解DAX計(jì)算表達(dá)式是如何計(jì)算的此衅,我們需要進(jìn)化到下一個級別,并深入了解計(jì)算列表篩選的工作方式以及它們是如何交互的亭螟。

? ? ? ?在本部分中挡鞍,將揭示DAX計(jì)算篩選的所有復(fù)雜性,并展示多個錯誤案例的表達(dá)式的示例媒佣,這些在實(shí)際運(yùn)用中可能會出現(xiàn)的錯誤示例匕累,只是因?yàn)槟氵€不完全了解它們的工作方式的緣故陵刹。一門語言的學(xué)習(xí)默伍,并不是一件容易的事。
? ? ? ?這一部分非常復(fù)雜衰琐。盡管如此也糊,如果你想更充分了解DAX并學(xué)習(xí)更多的知識。那么羡宙,學(xué)習(xí)這些詳細(xì)的看起來較復(fù)雜的內(nèi)容是必須的狸剃。如有必要,你需要多讀一遍或多遍該部分的內(nèi)容狗热。

? ? ? ?我們將在后面的內(nèi)容中介紹列表篩選的一些復(fù)雜場景钞馁。如果你想了解它到底對于你有多難虑省,你可以試著讀完下一部分,很可能你需要回到這里繼續(xù)閱讀僧凰。
? ? ? ? 為便于使用實(shí)例說明探颈,我們將開始涉及部分重要的DAX函數(shù)的功能學(xué)習(xí)及運(yùn)用。其實(shí)還是那句話:我們不希望把稍難一些的DAX知識放在靠前的部分來講训措。因?yàn)榈侥壳盀橹刮苯冢斜砗Y選的話題基本上已接近尾聲。
? ? ? ?這部分難于理解的復(fù)雜部分也是水到渠成绩鸣,在接近40式時(shí)怀大,列表篩選的話題基本結(jié)束,接下來是DAX計(jì)算的話題呀闻,也就是使用函數(shù)引用列表以及定義值列表創(chuàng)建DAX計(jì)算化借。這也將作為與隨后的綜合運(yùn)用部分的銜接。
? ? ? ? 這一式也將放于下一部分的系列中開始总珠。

? ? ? ? 未完待續(xù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末屏鳍,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子局服,更是在濱河造成了極大的恐慌钓瞭,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件淫奔,死亡現(xiàn)場離奇詭異山涡,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)唆迁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進(jìn)店門鸭丛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人唐责,你說我怎么就攤上這事鳞溉。” “怎么了鼠哥?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵熟菲,是天一觀的道長。 經(jīng)常有香客問我朴恳,道長抄罕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任于颖,我火速辦了婚禮呆贿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘森渐。我一直安慰自己做入,他們只是感情好冒晰,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著竟块,像睡著了一般翩剪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上彩郊,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天前弯,我揣著相機(jī)與錄音,去河邊找鬼秫逝。 笑死恕出,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的违帆。 我是一名探鬼主播浙巫,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼刷后!你這毒婦竟也來了的畴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤尝胆,失蹤者是張志新(化名)和其女友劉穎丧裁,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體含衔,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡煎娇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了贪染。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缓呛。...
    茶點(diǎn)故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖杭隙,靈堂內(nèi)的尸體忽然破棺而出哟绊,到底是詐尸還是另有隱情,我是刑警寧澤痰憎,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布票髓,位于F島的核電站,受9級特大地震影響信殊,放射性物質(zhì)發(fā)生泄漏炬称。R本人自食惡果不足惜汁果,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一涡拘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧据德,春花似錦鳄乏、人聲如沸跷车。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽朽缴。三九已至,卻和暖如春水援,著一層夾襖步出監(jiān)牢的瞬間密强,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工蜗元, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留或渤,地道東北人。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓奕扣,卻偏偏與公主長得像薪鹦,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子惯豆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評論 2 354

推薦閱讀更多精彩內(nèi)容