介紹DAX的時候,特別強調過一個重要的函式:CALCULATE,本文就來揭秘這個函式的計算原理以及它是如何影響上下文的。

CALCULATE的語法結構

語法:

CALCULATE(…)

第一個引數是計算表示式,可以執行各種聚合運算

從第二個引數開始,是一系列篩選條件,可以為空;如果多個篩選條件,用逗號分隔

所有曬選條件的交集形成最終的篩選資料集合

根據篩選出的資料集合執行第一個引數的聚合運算並返回運算結果

前文提到DAX函式可以更改外部上下文,現在透過例項來理解DAX中最精髓的函式CALCULATE的計算原理,並看看它是如何更改外部上下文的。

CALCULATE應用例項

匯入下面這個產品明細表:

PowerBI中最重要的函式:CALCULATE

新建一個度量值求每種產品的數量:

產品數量 = COUNTROWS(‘產品明細’)

因為每種產品的只有1行,所以求產品明細表的行數就相當於求各種產品的數量,把產品名稱和該度量值拖拽入矩陣表,

PowerBI中最重要的函式:CALCULATE

這裡外部上下文就是表格每行的行標籤。

01 | 篩選條件為空,不影響外部上下文

現在開始用CALCULATE函式建立一個度量值:

產品數量1 = CALCULATE([產品數量])

只是用了第一個引數,篩選條件為空,因為沒有內部篩選所以完全依賴外部上下文,出來的結果也和原度量值一致。

PowerBI中最重要的函式:CALCULATE

另外,介紹CALCULATE語法的時候說,第一個引數為聚合運算表示式,為什麼這裡沒有用聚合函式而只用了一個度量值呢?這是因為度量值[產品數量]本身就是一個聚合函式運算,實際上度量值[產品數量1]等同於這個:

產品數量1 = CALCULATE(COUNTROWS(‘產品明細’))

DAX函式可以直接引用已經建立好的度量值,可以使DAX函式看起來更簡潔、更具可讀性,這也是建議從最簡單的度量值開始建的原因。

02 | 新增限制條件,縮小上下文

建一個度量值[產品數量2],

產品數量2 = CALCULATE([產品數量],‘產品明細’[品牌]=“蘋果”)

PowerBI中最重要的函式:CALCULATE

發現只有蘋果的產品計數顯示出來,而其他品牌的資料沒有了,這是因為CALCULATE的第二個引數的限制,只篩選品牌為“蘋果”的,限制了外部的上下文,非蘋果的產品都不再運算。

03 | 結合ALL函式,擴大上下文

新建度量值[產品數量3],

產品數量3 = CALCULATE([產品數量],ALL(‘產品明細’))

PowerBI中最重要的函式:CALCULATE

這次的資料居然是所有產品的數量,這是因為篩選條件使用了ALL函式,ALL(‘產品明細’)的意思是清除產品明細表裡的所有篩選,外部篩選器不起作用了,每行統計的都是該表中的所有產品。

每行的資料都是9,你可能覺得這個ALL函式沒什麼用,運算的資料沒有什麼意義,會誤導人,實際上當然不是這樣,這個資料使用的地方非常多,比如我們想計算每個產品數量佔總產品數量的比重,直接寫個度量值:

產品佔比=[產品數量]/[產品數量3]

PowerBI中最重要的函式:CALCULATE

產品佔比就計算出來了,這就是統計總數的一個功能。

04 | 重置上下文

新建度量值[產品數量4],

產品數量4 = CALCULATE([產品數量],

all(‘產品明細’[產品名稱]),

‘產品明細’[類別]=“手機”)

先用ALL函式清除外部上下文,然後又新增了一個篩選條件,類別為“手機”的產品數量,那麼結果會是什麼樣的呢,

PowerBI中最重要的函式:CALCULATE

每一行產品的數量都是3,正好符合建立這個度量值的邏輯,被ALL清除行標籤的外部篩選後,從全部產品中統計品類為“手機”的產品的數量,所以每行都返回3。

透過以上幾個簡單的例子,可以領會到CALCULATE的計算邏輯,

透過從第二個引數開始的篩選條件,得到一個數據集合,並利用第一個引數執行聚合運算,這不就是DAX要實現的功能:提取有用資料並執行聚合運算嗎,所以說CALCULATE幾乎就是DAX本身,它就是實現DAX功能的引擎

,並能靈活的操控外部上下文,後面的資料分析也都離不開CALCULATE的身影。

文中案例資料在公眾號中請回復“CALCULATE案例”下載