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

? ? 第32式? CALCULATE與SUMIFS函數(shù)的行為對(duì)比

? ? ? 參閱《DAX圣經(jīng)》第4、5章相關(guān)部分?

? ? ? 你是否記得曾經(jīng)使用過Excel函數(shù)SUMIF( ),或者它的擴(kuò)展版新函表SUMIFS()?由于DAX本身也是一種函數(shù)式語言,某種情況下:
? ? ? CALCULAT ( )的行為類似于SUMIF/SUMIFS
? ? ? ?
只所以要講一下SUMIF/SUMIFS函數(shù),我們關(guān)注的是它們之間相同的函數(shù)功能所攜帶的行為,這對(duì)于理解DAX(特別是列表篩選)有莫大的幫助。同時(shí),也開始了我們研究CALCULATE()用于計(jì)算的關(guān)鍵主題。

? ? ? ? Excel中的SUMIF()和SUMIFS()函數(shù)功能是:它們聚合指定的一個(gè)列,但是在公式中篩選掉不符合定義的篩選條件的那些行。例如,你可以使用SUMIF( )來匯總某一列的銷售數(shù)據(jù),但只針對(duì)年份列中僅包含2012年的表中的那些行。
? ? ? ? 你不覺得這聽起來很熟悉嗎?這很像前面我們提到的DAX黃金法則 --- 先篩選,再計(jì)算(先列表,再值列表)”。這個(gè)相似的行為,在CALCULATE ()中被繼續(xù)。
? ? ? 但是,CALCULATE()又優(yōu)于SUMIF()/SUMIFS()的三個(gè)基本方式:

? ? ? 1、它有X系列函數(shù)的語法。這是三個(gè)優(yōu)勢(shì)中最小的一個(gè),但感覺也很棒。該優(yōu)勢(shì)(迭代)可以幫助你創(chuàng)建一個(gè)更快捷的公式。
? ? ? ? 2、它是一個(gè)“函數(shù)系列”,而不限于SUM/COUNT/AVERAGE。例如,在Excel中一直困擾著我們的是:沒有MAXIF()/MAXX函數(shù),也沒有MINIF(),當(dāng)然更加沒有STDEVIF()。CALCULAT ()實(shí)際上的條件計(jì)算是無限的——它允許你使用任何聚合函數(shù)(甚至是一個(gè)復(fù)雜的多函數(shù)表達(dá)式),并快速生成一個(gè)多IF版本。
? ? ? ? 3、它可以用于多個(gè)透視表 (作為度量的一部分),正常的SUMIF()則不能。

? ? ? 我們知道, CALCULAT ()函數(shù)參數(shù)為:CALCULATE([ ],<filter1>,<filter2>,…)
? ? ? 例如單條件的篩選計(jì)算:
? ? ? CALCULATE(SUM(Sales[Margin]),Sales[Year]=2001)

? ? ? 例如多條件(and)篩選計(jì)算:
? ? ? CALCULATE([Sales per Day],
? ? ? Sales[Year]=2002,Sales[ProductKey]=313)

? ? ? 讓我們?cè)購囊粋€(gè)簡單的透視表開始。例如一年來的[TotalSales]度量。好的,讓我們添加一個(gè)總是被篩選到年份=2002的新度量:

? ? ? [2002Sales] = CALCULATE([Total Sales],Sales[Year] =2002)

? ? ? 1、我們用一個(gè)<measure expression>的名稱來表示CALCULATE <計(jì)算列表>參數(shù)。任何合法的表達(dá)式都是可以的---包括預(yù)先定義的度量值名稱,或者可以用來定義度量的任何公式表達(dá)式;
? ? ? 2、請(qǐng)注意,在<篩選>參數(shù)中,2002沒有使用引號(hào)。這是因?yàn)槟攴萘惺菙?shù)值型的。如果它是一個(gè)文本列,則需要使用:= " 2002 ";
? ? ?
3、這一次我們只使用了一個(gè)<篩選>參數(shù),但是我們可以在一個(gè)CALCULATE公式中使用我們想要的多個(gè)(N)參數(shù);
? ? ? 4、新度量在每一種情況下都與2002年對(duì)應(yīng)的值相匹配!
? ? ? 5、之前的結(jié)果:在2002年每個(gè)月分別返回對(duì)應(yīng)的2002年全年的總銷售結(jié)果。這正是我們想要的結(jié)果!

? ? ? CALCULATE()是如何工作的?

? ? ? 我們之前已經(jīng)學(xué)習(xí)了多個(gè)CALCULATE( )的例子,讓我們來看看CALCULATE()是如何真正起作用的?因?yàn)檫@將在第一個(gè)示例中消除一些意料之外的結(jié)果。
? ? ? 關(guān)于CALCULATE() 有三個(gè)要點(diǎn),特別是關(guān)于<FILTER篩選器>參數(shù):

? ? ? 1、<filter-篩選>參數(shù)在度量CALCULATE的“篩選器”階段操作。它們修改了透視表提供的列表篩選——這發(fā)生在篩選器引用源列表之前,因此也就在聚合計(jì)算階段之前。
? ? ? 2、如果<filter>參數(shù)作用于已在主元列上,它將重寫該列的主篩選。在第一個(gè)例子中。 上面,透視表定義為Sales[Year]=2001(透視表篩選),但是,由于我們?cè)贑ALCULATE ()內(nèi)部公式中定義有Sales[Year]=2002,所以2001年透視表的“值”完全被CALCULATE ()覆蓋,并成為2002年(其實(shí)是被公式過濾掉了)。這就是,為什么在第一個(gè)例子中,2001年和2003年的CALCULSTE()以及小匯總值都返回了2002年的銷售數(shù)據(jù)。
? ? ? ? 3、如果<filter>參數(shù)作用于在透視表上沒有的列,則<filter>將完全添加到列表篩選。在我們的第二個(gè)例子中,我們?cè)谕敢暠砩戏胖糜蠸ales[MonthNum],而不是Sales[Year], Sales[Year]=2002的篩選器被應(yīng)用于進(jìn)入透視表中的當(dāng)前月份。因此,我們得到2002年銷售的第1個(gè)月,2002年銷售的第2個(gè)月......等所有與2002年交叉的月份。即先篩選的是年份,然后才是該年份下的所有當(dāng)前月份(透視表篩選)。
? ? ? 因而,是時(shí)候在該DAX評(píng)估步驟中填寫第2步了,以解釋CALCULATE插入本身的位置,從而允許更改篩選器篩選:

? ? ? DAX公式步驟2,修訂后的解釋:CALCULATE()對(duì)篩選篩選的影響。

? ? ? 先看看CALCULATE()的兩個(gè)有用的例子:到目前為止,我們使用的[2002年銷售]度量是向你展示CALCULATE()如何工作的好方法,但它似乎并不是很有用。所以需要再觀看兩個(gè)更廣泛、適用的例子。

? ? ? ? 示例1: 特定類型的事務(wù)計(jì)算

? ? ? 這是我們?cè)诹闶蹣I(yè)務(wù)中經(jīng)常遇到的:實(shí)際業(yè)務(wù)場(chǎng)景中,不是所有的交易都是正常的銷售,一些企業(yè)記錄了許多不同的交易類型,包括“正常交易”、“退款”、“促銷交易”交易方式。
? ? ? 假如我們的數(shù)據(jù)庫有這樣一個(gè)列,因此,我們將其導(dǎo)入到Sales表中(使用表屬性)。這里,我們看到它有三個(gè)值:我們現(xiàn)在想寫四種新方法,這里用英語定義:

“Regular” Sales “常規(guī)”銷售? ——? 交易類型為1。
“Promotional” Sales “促銷”銷售—交易類型為3。
“Refunds”“退款”表示為負(fù)數(shù),? ? —交易類型為2,

“Net Sales”--凈銷售= 常規(guī)銷售+ 促銷銷售 - 退款。
[Regular Sales]? ? = CALCULATE([TotalSales],Sales[TransType]=1)
[Promotional Sales]=CALCULATE([Total Sales],Sales[TransType]=3)[Refunds]=CALCULATE([Total Sales],Sales[TransType]=2) * -1)
[Net Sales]=[RegularSales]+[Promotional Sales]+[Refunds]

? ? ? 請(qǐng)注意,我們對(duì)(Refunds)的處理假定退款被記錄在我們的銷售表中有積極的價(jià)值。如果它們被記錄為負(fù)值,你可以從[Refunds]度量中去掉*-1的乘法計(jì)算。這個(gè)思路是不是很簡潔呢?
? ? ? 然后,繼續(xù)沿著實(shí)際的道路,讓我們看看銷售額有多少是由于促銷活動(dòng)引起的(即促銷銷售的占比情況),公式如下:

[Pct Sales onPromo]=[Promotional Sales] / ([Regular Sales]+[PromotionalSales])[Pct Saleson Promo] 度量告訴了我們,銷售收入來自促銷活動(dòng)的百分比。

? ? ? 示例2:自創(chuàng)建一段時(shí)期以來的增長。

? ? ? 我們將定義一個(gè)新的“基礎(chǔ)”元度量,它跟蹤在給定的時(shí)間段內(nèi)有多少客戶處于活動(dòng)狀態(tài):

? ? [ActiveCustomers] =DISTINCTCOUNT(Sales[CustomerKey])

? ? ? “基本度量”是指不涉及其他度量的計(jì)算度量。即該度量是一個(gè)純聚合定義的計(jì)算,就像上面的一樣。我們提過這個(gè)概念:稱之為“最簡單的DAX(度量)”。
? ? ? 現(xiàn)在,一項(xiàng)總是能告訴我們2001年有多少客戶活躍的指標(biāo)(第一年的業(yè)務(wù)):

? ? ? [2001 Customers]=CALCULATE([Active Customers],Sales[Year]=2001)

? ? ? [2001 Customers]結(jié)果是2001年的活躍客戶。然后,還有一項(xiàng)用來衡量自2001年以來客戶增長百分比基數(shù)的指標(biāo):
? ? ? ? [Customer Growth Since 2001] =
? ? ? ? DIVIDE ( [Active Customers] – [2001 Customers],[2001 Customers] )

? ? ? ? 4、CALCULATE中的<FILTER--篩選器>的“=”操作符的替代。

? ? ? 在CALCULATE ()的<filter>篩選參數(shù)中,不限于“=”操作符。你還可以使用:
< 、>、<=、>=、<>等。

? ? ? ? 并且,其實(shí)我們已經(jīng)知道:在單個(gè)CALCULATE ()中所有的<filter>參數(shù)都表現(xiàn)得像是被封裝在一個(gè)AND()函數(shù)中。換句話說,最后的當(dāng)前結(jié)果行必須同時(shí)滿足每個(gè)<filter>參數(shù)條件,以便被包含在CALCULATE中。你可以理解為:CALCULATE ()中所有的<filter>參數(shù)其實(shí)是一組篩選器,它們共同作用于計(jì)算列表,只有在所有篩選作用結(jié)束后,才輸出計(jì)算(被公式引擎接收)。
? ? ? ? 還有一種需要使用“OR(或者)” 操作情況,你可以使用“||” 操作符代替。例如: =CALCULATE([Total Sales],Sales[TransType]=1 || Sales[TransType]= 3)

? ? ? 當(dāng)在一個(gè)計(jì)算篩選器參數(shù)中使用 || 操作符時(shí),它只可以在單個(gè)列- 如[TransType]列的比較中使用。在不同的列(如TransType和Year)之間的比較中,不能使用||。

? ? ? 這解釋了[Active Customers]這類度量在透視表里的Grand Total (總計(jì)值)是如何工作的。讓我們?cè)倏匆幌逻@個(gè)透視表:

我們?cè)俅问褂肁LL

? ? [ Sumof all years] 所有年份的實(shí)際總和比[GrandTotal要高得多。

? ? ? 這一個(gè)很好的例子,說明了為什么要考慮對(duì)源表進(jìn)行評(píng)估,而不是在透視表本身中進(jìn)行評(píng)估。另外,我們已經(jīng)討論了很多關(guān)于列表篩選的內(nèi)容,但是到目前為止,我們還沒有討論過整個(gè)數(shù)據(jù)模型里的列表篩選。
? ? ? 其實(shí)很簡單:內(nèi)部數(shù)據(jù)模型表里代表沒有任何篩選器(總在一個(gè)全局性的數(shù)據(jù)模型里)。在這個(gè)前提下,就好像這一年的列值都不在某個(gè)行列上。為了排除這種情況,讓我們把從透視表中移走:從行里移除年份,結(jié)果與當(dāng)年的[Grand Total]值相匹配。這不是意外!

? ? ? 因?yàn)檫@是有道理的:2001年的一些客戶在2002年(后來)買了一些東西,同樣,2002年的一些客戶在2003年有過購買行為,依次類推。如果我們匯總每年的客戶總數(shù)(包含2001-2003三年的某些客戶數(shù)),這會(huì)不止一次地(重復(fù))計(jì)算那些“carryover”--客戶(最終得到24,376)。
? ? ? 但是,當(dāng)清除[年度]--年度篩選器時(shí):DISTINCTCOUNT (Sales[CustomerKey])運(yùn)行在一個(gè)未經(jīng)篩選的表上計(jì)算,并且只計(jì)算每個(gè)客戶一次!(執(zhí)行的是不重復(fù)列值的計(jì)算)結(jié)果是18,484,這是正確答案。

? ? ? 不要跳過上面的段落。它比一般的更值得關(guān)注。并不是每個(gè)[Grand Total]都是完整的(甚至于部分)。為了說明它,讓我們把年份拖到列上,并將月數(shù)增加到行:

? ? ? 當(dāng)前篩選有三種不同的總計(jì)數(shù):年、月總計(jì)數(shù)以及兩者的總和。
? ? ? 在一個(gè)透視表中,每一個(gè)數(shù)都是一個(gè)或多個(gè)篩選(一組篩選器)共同作用的結(jié)果—那么,透視表中一個(gè)或多個(gè)沒有結(jié)果的地方,其篩選作用同樣存在,并沒有消失。也就是說,雖然是沒有結(jié)果值,其篩選是存在的!即篩選的作用實(shí)際上表現(xiàn)為一種布爾值列表性質(zhì):篩選掉不符合條件的行,留下符合條件的那些行......。
? ? ? 我們后面還將學(xué)習(xí)到這種行為以及這種行為的運(yùn)用。

? ? ? 當(dāng)在行和列中添加更多字段時(shí),馬上會(huì)得到許多不同的總數(shù)變化。例如,當(dāng)你在另一個(gè)字段下嵌套時(shí),沒有什么真正的改變。讓我們?cè)诿磕甑南聜€(gè)月里的行為例:

? ? ? 層級(jí)并不能真正改變?nèi)魏螙|西。注意,2002年(2677)的合計(jì)是一個(gè)大的匯總值,匯總的并不是前面的值的和。 2001年是在列上(在之前的行中)單獨(dú)計(jì)算。在透視表度量單元的物理位置并不重要。只有它的“坐標(biāo)”是重要的。一個(gè)篩選器篩選的年份=2002,月=ALL與DAX里引擎完全相同,無論在哪里,年和月數(shù)字段都將位于-行、列、報(bào)表篩選器,或切片器上。

? ? 第33式? CALCULATE的列表在計(jì)算列與度量中的行為

? ? ? 還記得我們?cè)诘谝徊糠种校槍?duì)計(jì)算列、度量中的CALCULATE隱式與顯式的問題。這里用引用列表與定義值列表的概念再次解釋一次,這是學(xué)習(xí)DAX的一個(gè)理解的坎。

? ? ? 我們新建一個(gè)[銷售列]的[計(jì)算列]。定義公式:= SUM('訂單'[銷售額]) ,即針對(duì)[銷售額]計(jì)算。

? ? ? 結(jié)果并不是我們期待的,這是一個(gè)每行結(jié)果相同的值。當(dāng)然,我們知道該公式可用于度量公式。
? ? ? 如果需要作為計(jì)算列,則在公式 = SUM('訂單'[銷售額])前面加CALCULATE,我們稱之為:顯式定義列表篩選。即公式前面加上一個(gè)CALCULATE:
= CALCULATE ( SUM('訂單'[銷售額]))
? ? ? 這時(shí)候,只要顯式定義了列表篩選,那么,引擎會(huì)自動(dòng)創(chuàng)建該顯式列表篩選對(duì)應(yīng)的隱式行篩選(這是CALCULATE的行為之一)。如圖所示,計(jì)算列的公式能計(jì)算出正確的值:

? ? ? 前面我們采用:引擎的隱式與顯式列表的概念來理解的。在學(xué)習(xí)完DAX的列表引用與定義值列表的概念后,我們?cè)囍\(yùn)用它來解釋這個(gè)問題,然后后期運(yùn)用它進(jìn)行DAX的書寫。
? ? ? ? 我們知道:SUM('訂單'[銷售額]) 是一個(gè)值列表(具有行行為),一個(gè)DAX公式需要先有列表,然后再有值列表,也就是說任何一個(gè)DAX計(jì)算(甚至是其中的一個(gè)計(jì)算單元)都需要一個(gè)計(jì)算環(huán)境(列表范圍)。將:SUM('訂單'[銷售額]) 用于計(jì)算列計(jì)算,則這時(shí)候其列表環(huán)境是它使用的某個(gè)函數(shù)引用的列表(這里是'訂單'[銷售額]列),SUM('訂單'[銷售額]) 計(jì)算的總是該列表(因?yàn)闆]有任何其他的篩選!或者只有該列表篩選)。
? ? ? ? SUM('訂單'[銷售額])作為度量能夠計(jì)算正確,是因?yàn)樗诘挠?jì)算列表要不是整個(gè)數(shù)據(jù)模型,要不就是無限可能的計(jì)算列表集(可能被無數(shù)可能的列表篩選),它并不會(huì)針對(duì)其中的一個(gè)列表。
? ? ? ? 將SUM('訂單'[銷售額]) 用于計(jì)算列計(jì)算時(shí),我們期望它能產(chǎn)生不同的行值,相當(dāng)于告許引擎說:請(qǐng)你按這個(gè)行為來計(jì)算。不過問題是,引擎的內(nèi)部行為并不是由我們來定義的:即Sum( )中的計(jì)算列,引擎知道是該列表,也總是會(huì)使用它計(jì)算,結(jié)果是同樣的某你個(gè)值。
? ? ? 也就是說,引擎自動(dòng)識(shí)別該列表計(jì)算而不需要你刻意的定義。既然如此,只需要直接引用列表即可。

? ? ? ? 如圖,直接引用 =[銷售額]列,結(jié)果相當(dāng)于復(fù)制了某個(gè)列表。

? ? ? 當(dāng)然,這里還有一種情況:如果我們已定義了一個(gè)度量:[銷售額]=SUM('訂單'[銷售額]) ,那么,直接引用該度量名稱,也能正確計(jì)算。我們馬上說明原因:
? ? ? 用列表與值列表概念理解:Sum( )是一個(gè)值列表,你不能直接定義一個(gè)值列表來做為列表計(jì)算!你只有定義一個(gè)值列表,然后將其作為列表引用。
? ? ? ? 我們知道:要實(shí)現(xiàn)引用值列表作為列表參與計(jì)算,這有兩種方式:一種是使用列表函數(shù)迭代(即嵌套列表函數(shù)),但一旦嵌套了其他函數(shù),則計(jì)算將會(huì)改變(嵌套函數(shù)的功能也會(huì)發(fā)生作用)。
? ? ? ? 另一種是,使用CALCULATE(),這其實(shí)也是在原定義的值列表前嵌套了一個(gè)函數(shù),從而起到將原值列表引用為列表參與計(jì)算的功能,而不該表原值列表定義的計(jì)算!本列中,即CALCULATE(SUM('訂單'[銷售額])) ,這就是CALCULATE()的將隱式行行為(行篩選)轉(zhuǎn)換為相同的顯式化列表(列表篩選)的功能,更好的理解是:
? ? ? CALCULATE( )的引用"值列表"為顯式列表的行為。

? ? ? 如果是這樣,那么,只要是針對(duì)某個(gè)表的一個(gè)或多個(gè)計(jì)算列操作,該表格里所有的列都可以被定義為顯式列表參與計(jì)算。比如,我們可以直接定義兩個(gè)或多個(gè)標(biāo)量值列表之間的計(jì)算。如下圖的兩個(gè)時(shí)期列表的差異計(jì)算(相減)。

? ? ? 反過來,如前所說,上圖中的公式運(yùn)用在度量中,則會(huì)得到一個(gè)“錯(cuò)誤號(hào)”提示。原因當(dāng)然是:你不能直接引用列表作為值列表計(jì)算(這將缺少隱式的行篩選)。

? ? ? 所以,我們使用聚合函數(shù)的值列表行為特性,分別對(duì)兩個(gè)列加上聚合計(jì)算(所有迭代函數(shù)都具有隱式行篩選行為,這將針對(duì)兩列都創(chuàng)建了各自的行篩選)。如圖:結(jié)果正確。

? ? ? 當(dāng)然,如果你實(shí)在是還沒有理解,作為結(jié)論,你只需要記住:度量是一個(gè)需要定義的值列表,而計(jì)算列只需要直接引用列表--列表或結(jié)果列表,例如已定義了的某個(gè)度量:[銷售額]=SUM('訂單'[銷售額]) ,那么,直接引用該度量名稱,相當(dāng)于直接引用該度量值列表的結(jié)果列表,也能正確計(jì)算。
? ? ? 這時(shí)候,你可以理解為任何一個(gè)度量其實(shí)就是一個(gè)省略了CALCUALTE的值列表。因此,凡是CALCUALTE([度量],篩選1...)形式的公式(CALCULATE的第一參數(shù)為度量)時(shí),可以將公式簡寫:
? ? ? ? CALCUALTE([度量],篩選1...)= [度量] (篩選1...)

? ? ? ? 例如:CALCULATE([銷售額], Sales[城市]="上海") 可寫成:
? ? ? ? ? ? ? ? ? [銷售額] (Sales[城市]="上海")

? ? 第34式? CALCULATE的列表篩選行為(中級(jí))

? ? ? 現(xiàn)在我們使用一個(gè)官方的DAX實(shí)例,來加深對(duì)CALCULATE()的列表引用與定義值列表以構(gòu)成DAX篩選+計(jì)算的理解。
? ? ? 業(yè)務(wù)描述:我們希望求得財(cái)務(wù)時(shí)期表中的以5天或6天(非正常周數(shù)7天)定義的財(cái)務(wù)周數(shù)列--[周序號(hào)]列,并期望按此周數(shù)列條件計(jì)算每周的訂單數(shù)量。以下是提供的公式:

財(cái)務(wù)周:=CALCULATE(SUM('業(yè)務(wù)表'[需求量]),
FILTER(ALL('日歷'),'日歷'[周序號(hào)]=MAX('日歷'[周序號(hào)])
&&'日歷'[日期]<=MAX('日歷'[日期])
&&NOT(ISBLANK(MAX('業(yè)務(wù)表'[交貨日期])))))

? ? ? 因?yàn)楣讲捎玫氖峭暾呢?cái)務(wù)日歷表,可能那些當(dāng)前時(shí)期之后沒有訂單數(shù)據(jù)的未來日期,仍可能有數(shù)據(jù)存在。因而,在FILTE()函數(shù)中增加一個(gè)條件:NOT(ISBLANK(MAX('訂單'[交貨日期]),即排除那些當(dāng)前沒有數(shù)據(jù)(交貨時(shí)期)的時(shí)期篩選行。

? ? ? 要想理解該公式,關(guān)鍵是對(duì)公式中FILTER()函數(shù)參數(shù)的理解,但這并不是一個(gè)簡單的問題,它涉及到FILTER、ALL兩個(gè)函數(shù)的組合所觸發(fā)的DAX內(nèi)部的計(jì)算邏輯。
? ? ? 我們有種感覺:CALCULATE似乎總習(xí)慣于FILTER函數(shù)搭檔,而FILTER()的參數(shù)中有時(shí)常出現(xiàn)ALL().....。
? ? ? CALCULATE與FILTER函數(shù)似乎總是被提起,有人稱CALCULATE(...FILTER(...))的方式為DAX的萬能組合公式,雖然有點(diǎn)夸張,但也說明了這種DAX方式是很重要的書寫DAX的形式(也可以說是DAX的一種定式)。
? ? ? 其根本原因大概是因FILTER的特點(diǎn)決定的,也就是前面我們所說的:FILTER()作為列表結(jié)果而執(zhí)行著標(biāo)量值列表的功能。換句話說,F(xiàn)ILTER() 總以值列表形態(tài)(具有行行為--你通常理解的遍歷表)存在著,但它首先是一個(gè)值列表結(jié)果(即作為列表可以被引用,度量也有這個(gè)功能)。你可以回過頭看看第6部分的內(nèi)容。這里把其中例舉的兩個(gè)例子拿出來再說說:

? ? ? 1) = COUNTROWS ( FILTER (Sales, Sales[Unit Price] > 100))
? ? 2) = COUNTROWS ( ALL (Sales), Sales[Unit Price] > 100))

? ? ? ? 我們前面提供的是一個(gè)很通俗的區(qū)別方法:公式 1),對(duì)于FILTER函數(shù),有一個(gè)通常的理解:它是一個(gè)行篩選器,具有遍歷表的每一行的行行為,因而,它的結(jié)果表是按定義的值列表?xiàng)l件一行一行判斷并找出來的,即內(nèi)部引擎一行一行掃描--遍歷表。而公式 2)則是直接“引用”一個(gè)列表篩選得出的。直觀上,你回話覺得公式 2)似乎要運(yùn)行得快一些(這要視數(shù)據(jù)模型等具體情況,討論這個(gè)還有點(diǎn)過早)。

? ? ? 出于重要性,我們?cè)倏匆粋€(gè)已經(jīng)出現(xiàn)的公式:
? ? ? CALCULATE([銷售量],FILTER('時(shí)期表', [銷售量]<100))

? ? ? 該公式中,我們知道,對(duì)了,還是簡單分下步驟,以便于理解:
? ? ? 1)先有列表。FILTER引用時(shí)期表(FILTER的第一參數(shù));
? ? ? 2)再有值列表。然后,第二參數(shù)定義了一個(gè)值列表:[銷售量]<100(布爾值篩選);
? ? ? 3)該布爾值條件對(duì)引用的時(shí)期表進(jìn)行篩選,得到一個(gè)時(shí)期表的子集表。也就是:時(shí)期表的范圍已發(fā)生改變!。
? ? ? 請(qǐng)記住,這里是關(guān)鍵之處,由于時(shí)期表的范圍已被改變,這時(shí)候的時(shí)期表應(yīng)該是一個(gè)值列表(具有行的行為),FILTER()在執(zhí)行著標(biāo)量值列表的功能;但同時(shí),該值列表又被CALCULATE作為列表“引用”(使用的是該值列表的全集列表),以作為CALCULATE的篩選列表,由此時(shí)期表的子集列表篩選[銷售量]度量所在的計(jì)算列表。這是FILTER()同時(shí)具有的作為列表結(jié)果的功能。
? ? ? ? 這里還需要理解的是:該公式中,FILTER()首先篩選的是時(shí)期表,而不是計(jì)算所在的事實(shí)表,由于事實(shí)表與時(shí)期表之間的列表關(guān)系,通過時(shí)期表的篩選,進(jìn)而篩選出計(jì)算列表集,然后,度量在該結(jié)果列表集下計(jì)算。
? ? ? 這就是該公式中發(fā)生的整個(gè)事情。我們現(xiàn)在回過頭來再看看前面提到的那個(gè)公式,它看起來好像要復(fù)雜一些,但理解方式是一樣的:

財(cái)務(wù)周:= CALCULATE(SUM('業(yè)務(wù)表'[需求量]),
FILTER(ALL('日歷'),'日歷'[周序號(hào)]=MAX('日歷'[周序號(hào)])
&&'日歷'[日期]<=MAX('日歷'[日期])
&&NOT(ISBLANK(MAX('業(yè)務(wù)表'[交貨日期])))))

? ? ? ? 這里的FILTER部分是:=FILTER(數(shù)據(jù),篩選條件),本例中,第一參ALL('日歷表'),根據(jù)ALL函數(shù)的功能,表示為:"取消"施加在"日歷表"的所有篩選,也就是說取整個(gè)日歷表的所有數(shù)據(jù)(這點(diǎn)上,相當(dāng)于直接引用一個(gè)表,請(qǐng)注意,這里的問題是前面留下來的一個(gè)問題:既然與直接引用一個(gè)表結(jié)果相同,為什么還要使用ALL())。

? ? ? 本來,我們知道:"業(yè)務(wù)表"的"交貨日期"和"日歷表"的"日期"字段建立有兩個(gè)表格之間的關(guān)聯(lián)(存在關(guān)系),但是在這里,因?yàn)锳LL()函數(shù)的作用,這讓原來"日歷表"與"業(yè)務(wù)表"之間建立的"字段關(guān)系"被"暫時(shí)"取消了,這時(shí)候,兩個(gè)表格將重新執(zhí)行如下方式的操作(當(dāng)然,這個(gè)操作是在我們給FILTER()函數(shù)下了ALL('日歷表')指令后,由引擎內(nèi)部自動(dòng)完成的)。
? ? ? 當(dāng)在 FILTER()函數(shù)中使用了ALL() 后(其實(shí)這時(shí)候,我們很為難:是說FILTER引用了列表,還是說由ALL定義了值列表?這就是前面講到的,F(xiàn)ILTER的兩個(gè)同時(shí)具備的特別行為)。這時(shí),兩個(gè)表格--"業(yè)務(wù)表"和"日歷表"原有的關(guān)系暫時(shí)被拆開,然后,兩個(gè)表格之間又建立了如下的以一對(duì)多關(guān)系(即左連接關(guān)系)。
? ? ? 也就是說,左邊表格的每一條記錄與右邊表格的每一條記錄建立了關(guān)系,形成一條條新的記錄。我們假設(shè)左表有15條記錄,右表有15條記錄(當(dāng)然兩個(gè)表格的記錄數(shù)不必相等),那么,最后形成的大表格的記錄數(shù)可能是15*15=225條行記錄...。
? ? ? ? 好了,關(guān)于 FILTER()函數(shù)的第一個(gè)參數(shù)的作用我們講完了,現(xiàn)在我們理解一下FILTER()函數(shù)的第二個(gè)參數(shù)的作用,F(xiàn)ILTER()函數(shù)的第二個(gè)參數(shù)如下:
? ? ? '日歷'[周序號(hào)]=MAX('日歷'[周序號(hào)])
? ? ? &&'日歷'[日期]<=MAX('日歷'[日期])
? ? ? &&NOT(ISBLANK(MAX('業(yè)務(wù)表'[交貨日期])

? ? ? 這里,F(xiàn)ILTER()第二個(gè)參數(shù)的功用是在第一個(gè)參數(shù)所獲得的數(shù)據(jù)的基礎(chǔ)上作進(jìn)一步的篩選。你已經(jīng)知道,通過FILTER()第一個(gè)參數(shù)ALL("日歷表")獲得了一個(gè)225行大表格,這將被第二個(gè)參數(shù)進(jìn)行篩選。
? ? ? 在這里,F(xiàn)ILTER()函數(shù)的第二個(gè)參數(shù)由三個(gè)條件構(gòu)成。這三個(gè)條件需要同時(shí)滿足,即必須同時(shí)為TRUE的行才保留在篩選結(jié)果中。請(qǐng)自行理解就不做過多說明。
? ? ? 我們來小結(jié)一下:FILTER(ALL('日歷'), ...)的行為,因?yàn)榭梢詳[脫原有列表關(guān)系的影響,并使用最大的全集列表來創(chuàng)建一個(gè)新的關(guān)系列表(左連接寬表),可能擁有有更大的事實(shí)行計(jì)算,并避免錯(cuò)失某些行值的計(jì)算。而FILTER('日歷', ...)的直接引用列表的行為,由于始終受原有列表關(guān)系的影響,由于在度量計(jì)算中,你不能直接引用一個(gè)列表計(jì)算,它將被一個(gè)或多個(gè)值列表篩選。其靈活性不如采用ALL()的方式。
? ? ? 當(dāng)然,我們只就列表與值列表的概念來分析,實(shí)際的更多情況,在后續(xù)的內(nèi)容中還會(huì)講到。
? ? ? 這里,還有一個(gè)問題,那就是公式中的MAX()函數(shù)的作用,根據(jù)前面所說:凡是結(jié)果為一行一列(相當(dāng)于Excel中的一個(gè)單元格)的函數(shù)都是標(biāo)量值列表。只有這樣才能寫成如下形式的代碼:
? ? ? '日歷表'[五天序號(hào)]=MAX('日歷表'[五天序號(hào)])
? ? ? '日歷表'[日期]<=MAX('日歷表'[日期]))
? ? ? ? 即:“列表=某個(gè)值列表”的形式,以實(shí)現(xiàn)一個(gè)多行一列的數(shù)據(jù)表格中的所有數(shù)值和單個(gè)或某個(gè)范圍的數(shù)值進(jìn)行比較。
? ? ? ? 另外,我們已經(jīng)知道:CALCULATE()函數(shù)的語法是:
? ? ? ? = CALCULATE(計(jì)算列表,篩選條件1,篩選條件2,…)
? ? ? ? 使用FILTER()函數(shù),該函數(shù)的語法可以變化為:
? ? ? ? = CALCULATE(計(jì)算列表,F(xiàn)ILTER(數(shù)據(jù)列表,篩選條件(值列表)))
? ? ? ? 長期以來,關(guān)于這兩個(gè)DAX代碼的方式與行為,是不是了解得多了一些?

? ? 第35式? CALCULATE的列表篩選行為(中高級(jí))

? ? ? ? (請(qǐng)參考《DAX圣經(jīng)》中的第4、第5章相關(guān)內(nèi)容)

? ? ? 既然已經(jīng)了解了CALCULATE函數(shù)許多的基礎(chǔ)知識(shí),或者至少了解了它為什么如此有用,下面的內(nèi)容將專門討論其用法的各種示例。深入研究和理解它是很重要的。

? ? ? 事實(shí)上,CALCULATE本身是一個(gè)非常簡單的函數(shù)。其復(fù)雜性此我們給予它的重要性)來自這樣一個(gè)事實(shí):使用CALCULATE,你將被迫考慮列表篩選,并且可能在一個(gè)公式中會(huì)有多個(gè)篩選,這使得很難遵循其計(jì)值流。根據(jù)經(jīng)驗(yàn),通過實(shí)例學(xué)習(xí)是理解CALCULATE工作流和列表篩選的最佳方法。

? ? 1、單列的篩選

? ? ? 使用CALCULATE的最簡單方式是篩選單個(gè)列。例如,假設(shè)要?jiǎng)?chuàng)建一個(gè)始終返回Black--黑色產(chǎn)品銷售的度量,而不管在顏色上的篩選是什么。這個(gè)公式很容易寫成:

[SalesAmountBlack] =
? ? ? ? CALCULATE(SUM( Sales[SalesAmount] ),
? ? ? ? ? ? Product[Color] ="Black")

? ? ? 該度量[SalesAmountBlack]總是顯示Black--黑色產(chǎn)品的銷售情況,而不受當(dāng)前的篩選器的篩選影響。可以看到,[SalesAmountBlack]顯示的總是黑色產(chǎn)品的銷售情況,即使在篩選器的篩選里選擇了不同顏色的行中也是如此。
? ? ? ? 如果關(guān)注的是第三行 :Product[Color] ="Black",這就是所發(fā)生的事情:公式在篩選器篩選中啟動(dòng)了CALCULATE (),其中計(jì)算所在的顏色行的唯一值是Blue。然后,CALCULATE定義一個(gè)新的條件(Color=Black),當(dāng)強(qiáng)制將它應(yīng)用到新的篩選器篩選時(shí),它替換了現(xiàn)有的篩選條件,刪除了Blue上的其他篩選器,并將其替換為列值=“Blue”的篩選器,而且,在所有行(即所有顏色行)上都會(huì)如此,這也是為什么看到所有行為相同編號(hào)的原因。
? ? ? 顯然,由于CALCULATE覆蓋所選內(nèi)容的唯一列是顏色,所以其他列將繼續(xù)維護(hù)它們的篩選器。例如,如果將[日歷年]列放在列上,則可以看到所有顏色行上的結(jié)果也都是相同的,不同年份的結(jié)果也是相同的,如圖所示:

? ? ? 圖中[ SalesAMountBlack]只覆蓋掉顏色:它仍然服從對(duì)其他列(年份)的篩選。
? ? ? 篩選單個(gè)列很簡單。一個(gè)不太明顯的事實(shí)是:如果使用條件作為篩選器進(jìn)行計(jì)算,一次只能篩選一個(gè)列。例如,可能希望創(chuàng)建一個(gè)度量,該度量只計(jì)算單價(jià)至少是單位成本兩倍的產(chǎn)品的銷售額??梢栽囋囘@個(gè)公式:

[HighProfitabilitySales]=
CALCULATE(SUM( Sales[SalesAmount] ),
? ? ? Product[Unit Price] >= Product[Unit Cost]*2)

? ? ? ? 可以看到,這一次,條件涉及到兩列:Unit Cost和 Unit Price--單位成本與單位價(jià)格。即使DAX可以輕松地計(jì)算出每個(gè)產(chǎn)品的條件,它也不允許這種語法。
? ? ? 原因是:在計(jì)算過程中CALCULATE無法確定是應(yīng)該替換單價(jià)、單位成本上的任何現(xiàn)有篩選器條件,還是不替換它們中的任何一個(gè)?實(shí)際上,如果試圖編寫上面的公式,則會(huì)得到一個(gè)錯(cuò)誤:該表達(dá)式包含多個(gè)列,但只有一個(gè)列可以用于True/False表達(dá)式,即用作表篩選器表達(dá)式。
? ? ? 當(dāng)然,我們已經(jīng)不需要這樣去理解,如前面所說的:“列表=列表”的方式是無法生成這樣的公式的(錯(cuò)誤的),只能使用:列表=“值列表”的方式來定義這種布爾語法(正確的)。
? ? ? 如果需要在條件中使用多列來調(diào)用計(jì)算,則需要使用不同的語法,該語法需要定義一個(gè)值列表,而不是一個(gè)條件。編寫前一個(gè)表達(dá)式的正確方法是使用以下語法:

[HighProfitabilitySales] =
CALCULATE(SUM( Sales[SalesAmount] )
FILTER(Product,Product[Unit Price] >= Product[Unit Cost] *2))

? ? ? 與前一個(gè)公式不同的是,這一次,我們沒有直接使用布爾表達(dá)式,而是使用了FILTER()的列表語法功能,來作為CALCULATE的篩選器參數(shù)。這時(shí),不僅篩選了兩個(gè)列,還篩選了整個(gè)Product表。在圖中,可以看到[HighprofitabilitySales]度量的執(zhí)行結(jié)果:

? ? ? 這種情況下,CALCULATE的計(jì)算條件:FILTER()的結(jié)果是包含多個(gè)列的表(它包含Product表的所有列)。
? ? ? 當(dāng)新的條件插入到篩選器環(huán)境中時(shí),實(shí)際上全部現(xiàn)有的Product--產(chǎn)品條件都將被這個(gè)新的篩選器取代。換句話說,使用實(shí)際表作為FILTER()函數(shù)的第一個(gè)參數(shù),可以有效地替換該表中所有列的所有條件。
? ? ? 在閱讀了前面的解釋之后,你應(yīng)該注意到這里有些東西并不完全清楚:FILTER中的篩選器表達(dá)式計(jì)算替換了Product表上所有以前存在的篩選器,因?yàn)镕ILTER返回的表包含Products的所有列。然而,我們的公式返回的值對(duì)于每一行都是不同的。
? ? ? 就我們到目前為止所了解到的情況而言,要么DAX沒有替換掉顏色行篩選器,要么發(fā)生了更復(fù)雜的事情。因?yàn)?,我們已?jīng)知道DAX取代了顏色篩選器,所以,我們需要更多的研究來理解CALCULATE的確切流程。下面的代碼是度量的公式:我們對(duì)行進(jìn)行了編號(hào),以便更容易地引用公式的各個(gè)部分。

1,CALCULATE(
2,SUM( Sales[SalesAmount] )
3,F(xiàn)ILTER(
4,Product ,
5,Product[UnitPrice] >= Product[Unit Cost] *2
6? )
7 ,
8 )

? ? ? 第一個(gè)是CALCULATE函數(shù)。我們知道,作為CALCULATE的第一步:它首先定義篩選器參數(shù)。在執(zhí)行任何其他操作之前,CALCULATE將從第3行的FILTER表達(dá)式開始。 我們已經(jīng)很熟悉:FILTER是一個(gè)迭代器,它遍歷Product表(參見第4行)。然而,F(xiàn)ILTER將不會(huì)遍歷所有Product表:它將只能遍歷在當(dāng)前篩選器篩選中可見的那些行?,F(xiàn)在的問題是:
? ? ? 該“DAX在第4行引用(或定義)Products表的FILTER()篩選環(huán)境是什么?”
? ? ? 請(qǐng)記住,這時(shí),CALCULATE()仍然沒有創(chuàng)建其新的計(jì)算篩選。稍后,它是在對(duì)FILTER進(jìn)行計(jì)算之后,才會(huì)執(zhí)行篩選。
? ? ? 這可以推斷出:CALCULATE()的篩選器是在原始篩選器篩選下計(jì)算的,而不是在FILTER創(chuàng)建的篩選下計(jì)算的。雖然這看起來很明顯,但這種簡單的考慮卻是許多DAX公式中錯(cuò)誤的主要來源之一。

? ? ? 在第4行的產(chǎn)品Product表,是指在原始篩選器篩選中可見的那些產(chǎn)品。然后CALCULATE將刪除顏色的現(xiàn)有篩選器,但是,這樣的篩選器現(xiàn)在已經(jīng)包含在FILTER篩選器的結(jié)果中,從而導(dǎo)致當(dāng)前透視表的行為。正確理解篩選的流動(dòng)順序是很重要的:在CALCULATE的表達(dá)式中,顏色的篩選器會(huì)被CALCULATE替代,而不是在CALCULATE里的FILTER。
? ? ? 換句話說,CALCULATE中的篩選參數(shù)在之前的列表篩選中進(jìn)行了計(jì)算。稍后,才會(huì)創(chuàng)建其新的列表篩選,并在此篩選下,計(jì)算其表達(dá)式參數(shù)。
? ? ? 如果你對(duì)于前面的一段解釋很迷茫,那么,你需要使用前面關(guān)于FILTER的行為方式的解釋,你只需記住一句話即可:FILTER()的結(jié)果是一個(gè)值列表,該值列表被CALCULATE()引用為列表篩選(篩選計(jì)算列表,而不是FILTER引用的數(shù)據(jù)列表!),要獲得完整的理解,我們?cè)俅伪容^一下前面提到的ALL方式的公式:

[HighProfitabilityALLSales] :=
CALCULATE(SUM( Sales[SalesAmount] )
FILTER? (ALL(Product),
Product[Unit Price] >= Product[Unit Cost] *2))

? ? ? 這一次,沒有使用FILTER(Product),而是FILTER(ALL(Product)。這時(shí),F(xiàn)ILTER() 不只是迭代某個(gè)顏色的產(chǎn)品,而總是迭代所有Product-產(chǎn)品,而且,由于CALCULATE()替換了顏色上的篩選器。

? ? ? 圖中[HighProfitabilityALLSales]度量顯示,在CALCULATE()中有效地替換了顏色上的篩選器。即[HighProfitabilityALLSales]總是顯示所有高利潤產(chǎn)品的銷售,有效地忽略了原有的顏色篩選器,讓我們開始從第一個(gè)例子中得出一些結(jié)論:

? ? ? 1)你可以在CALCULATE()中使用布爾值條件,但使用它們,需要表達(dá)式中只針對(duì)某一個(gè)列引用,否則會(huì)出現(xiàn)語法錯(cuò)誤:
? ? ? 2)可以在引用中使用FILTER() 或任何其他表函數(shù)作為篩選器參數(shù)。本例中,表中所有列都是新篩選器篩選的一部分。這意味著CALCULATE()將取代這些列上的任何現(xiàn)有篩選器:

? ? ? 3)如果使用FILTER篩選器,則CALCULATE()在原始篩選器篩選中計(jì)算其篩選器。另一方面,如果使用布爾條件,則CALCULATE將替換現(xiàn)有的篩選器篩選,但只作用于受影響的列。

? ? ? 有人問:那么,CALCULATE()里面如果有多個(gè)列表篩選,這些篩選有沒有順序問題?其實(shí)是有的,一般,盡可能首先將能篩選出列表范圍少的列表子集的那個(gè)篩選放在前面要好(因?yàn)楹竺婧Y選的范圍跟著少一些,特別是數(shù)據(jù)量較大時(shí)很明顯)。

? ? ? 2、多列表?xiàng)l件下的篩選

? ? ? 使用多個(gè)篩選器時(shí),CALCULATE在創(chuàng)建新篩選器篩選時(shí)執(zhí)行邏輯條件AND連接的一組篩選條件。所以,如果想篩選所有由"Tailspin Toys"制造、并且(AND)產(chǎn)品顏色--黑色的產(chǎn)品,可以使用這樣的表達(dá)式:

[Calculate Version] :=
CALCULATE(SUM( Sales[SalesAmount] ),
Product[Brand] ="Tailspin Toys",
Product[Color] ="Black")

? ? ? 因?yàn)镃ALCULATE將這兩個(gè)條件放入其中,所以,你可能會(huì)認(rèn)為表達(dá)式與這個(gè)表達(dá)式是等價(jià)的:

[FILTER Version] :=
CALCULATE(SUM( Sales[SalesAmount]),
FILTER(Product,
AND(Product[Brand] ="TailspinToys",Product[Color] ="Black")))

? ? ? 實(shí)際上,這兩種表達(dá)方式是不同的,前面我們解釋了原因。你應(yīng)該已經(jīng)了解了這一點(diǎn),但由于主題的復(fù)雜性以及后面討論的概念的重要性,這里值得重復(fù)一遍。在包含布爾表達(dá)式的公式中,brand-品牌和color-顏色都忽略了現(xiàn)有的列表篩選(即直接定義值列表篩選):而在帶FILTER()的公式中,在應(yīng)用公式之前,對(duì)于兩個(gè)列都考慮了預(yù)先存在的篩選器。
? ? ? ? 因此,[CalculateVersion]總是返回black的、TailspinToys的銷售額,而[FILTER

Version]只在它們已經(jīng)存在于預(yù)先存在的篩選器篩選中時(shí)才返回銷售:否則它返回一個(gè)空值??梢栽谙聢D中觀察到這種行為:

? ? ? 很明顯,這兩個(gè)公式導(dǎo)致了不同的計(jì)算,即使它們看起來非常相似,不同之處在于:FILTER()篩選器迭代了由外部當(dāng)前篩選篩選的表,請(qǐng)記住以下公式:

[Sales of Tailspin Toys] :=
CALCULATE(SUM( Sales[SalesAmount] ),
Product[Brand] ="Tailspin Toys")

相當(dāng)于下一個(gè):

[Sales of Tailspin Toys] :=
CALCULATE(SUM( Sales[SalesAmount] ),
FILTER(ALL ( Product[Brand] ),
Product[Brand] ="Tailspin Toys"))

? ? ? 在第二個(gè)公式中,通過使用ALL(Product[brand]),來明確要求DAX:僅針對(duì)er[制造商]列而忽略當(dāng)前的篩選器篩選。我們?cè)僭趺磸?qiáng)調(diào)理解這些公式的行為的重要性也不為過。即使這里使用的表達(dá)式只是用于教育目的,在編寫自己的表達(dá)式時(shí)也會(huì)遇到類似的情況,并確保最終不會(huì)看到一些奇怪的結(jié)果。為了理解公式的行為,你必須了解DAX中的篩選行為。
? ? ? 篩選在一列上工作,上面所述的示例能工作得很好。如果涉及多列,我們可能會(huì)嘗試通過嘗試以下公式將等效擴(kuò)展到多個(gè)列表的場(chǎng)景:

FilterAll Version :=
CALCULATE(SUM(Sales[SalesAmount]),
FILTER(ALL(Product),
AND(Product[Brand]="Tailspin Toys",Product[Color]="Black") ) )

? ? ? 這個(gè)公式并不符合在本部分中看到的第一個(gè)公式所解決的要求。
? ? ? 如果使用ALL(Product),它將通過忽略整個(gè)表上的篩選器,來達(dá)到忽略其中兩列的當(dāng)前篩選(AND定義的兩列)。但是,通過忽略整個(gè)表上的當(dāng)前篩選,仍然可以得到不同的行為。為了看到效果,需要使透視表更加復(fù)雜一些。在下圖中,我們?cè)谛兄刑砑宇悇e名稱:

? ? 圖中,使用FILTER和Product表中的ALL內(nèi)容仍然不能解決這個(gè)問題。

如所見,[Filter All Version]會(huì)忽略整個(gè)Product表上的FILTER篩選,甚至顯示了Computers category---計(jì)算機(jī)類別的值,而[CalculateVersion]會(huì)顯示一個(gè)空白值。原因是[CalculateVersion]只忽略color 和model--顏色和模型名稱的當(dāng)前篩選,而[Filter All Version]則忽略整個(gè)表上的篩選器,當(dāng)然,這同時(shí)會(huì)忽略category--類別列。

? ? ? 為了找到正確的公式,必須考慮列而不是表。我們既不能提供Product表做篩選(因?yàn)樗暾脑己Y選器:行、列篩選,即使用的值全集的列表),也不能提供ALL(Product)(因?yàn)檫@將忽略所有的篩選器)。
? ? ? 正確的思路是:我們需要引用一個(gè)Product表來計(jì)算,并在該表中,刪除制造商的篩選器,但是,其他列表中現(xiàn)有的任何篩選器仍需要處于活動(dòng)狀態(tài)。我們已經(jīng)知道,只有CALCULATE函數(shù)具有該功能。

? 未完待續(xù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容