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


CALCULATE的語法結構

語法:

CALCULATE(<expression>,<filter1>,<filter2>…)

  • 第一個參數是計算表達式,可以執行各種聚合運算
  • 從第二個參數開始,是一系列篩選條件,可以為空;如果多個篩選條件,用逗號分隔
  • 所有曬選條件的交集形成最終的篩選數據集合
  • 根據篩選出的數據集合執行第一個參數的聚合運算並返回運算結果

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

CALCULATE應用實例

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

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

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

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

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

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

現在開始用CALCULATE函數創建一個度量值:

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

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

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

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

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

02 | 添加限制條件,縮小上下文

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

產品數量2 = CALCULATE([產品數量],產品明細[品牌]="蘋果")

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

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

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

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

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

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

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

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

04 | 重置上下文

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

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

all(產品明細[產品名稱]), 產品明細[類別]="手機")

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

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

通過以上幾個簡單的例子,可以領會到CALCULATE的計算邏輯,通過從第二個參數開始的篩選條件,得到一個數據集合,並利用第一個參數執行聚合運算,這不就是DAX要實現的功能:提取有用數據並執行聚合運算嗎,所以說CALCULATE幾乎就是DAX本身,它就是實現DAX功能的引擎,並能靈活的操控外部上下文,後面的數據分析也都離不開CALCULATE的身影。

文中案例數據在公眾號中請回復「CALCULATE案例」下載

推薦閱讀:

相关文章