DAX 第二篇:計算上下文

悅光陰發表於2019-07-19

計算上下文是計算公式的環境,任何DAX表示式都是在上下文中求值的。行上下文和篩選上下文是DAX中僅有的上下文型別,把這兩種上下文稱為計算上下文。計算上下文用於限定公式計算的環境,當上下文變化時,相同的公式會計算出不同的結果。

一,計算上下文

在PowerBI中建立的計算列是在行上下文中執行計算,建立的度量(meassure)是在篩選上下文中執行計算。

  • 行上下文是一個總是包含一行的上下文,DAX在建立計算列時自動定義行上下文。
  • 篩選上下文是由切片器(Slicer)、使用者選擇的分組欄位、關係的篩選方向等過濾器共同定義的,而DAX利用篩選上下文來計算公式(度量)。

二,行上下文

行上下文僅僅存在於表的同一行中,作用是對錶中同一行的不同列,應用公式,逐行計算出公式的結果。

例如,建立一個計算列 Profit,利潤的公式是由商品的   銷售額 - 稅額 - 成本 - 運費,DAX公式如下所示:

Profit = FactSales[SalesAmount]-FactSales[TaxAmt]-FactSales[TotalProductCost] - FactSales[Freight]

DAX逐行應用公式,對於表中每一行,都會根據公式,把同一行上的不同列的值代入到公式中,計算出公式的結果:

實際上,用於執行計算的行並沒有儲存在公式中,而是定義在行上下文中。從邏輯的角度來講,計算列的工作流程是:

  • 當你定義計算的列時,DAX從表的第一行開始迭代,首先建立了包含該行的行上下文並對錶達式求值,
  • 然後它移到第二行,再次求出表示式;
  • 這發生在表格中所有的行中,如果你有100萬行,你可以認為DAX建立了100萬行上下文來評估這個公式100萬次。

三,篩選上下文

建立的度量在篩選上下文中執行公式的計算,篩選上下文是對錶應用過濾器之後,資料被篩選之後的上下文。篩選上下文是由過濾器共同作用的,過濾器主要有:切片器(Slicer),分組列和關係。DAX的強大之處在於,DAX不僅能夠自動應用篩選上下文,還支援修改、清除和重定義篩選上下文。
1,自動應用篩選上下文
在PowerBI的FactSlaes表中定義一個度量,用於計算總的銷售額:
Measure SumOfAccount = CALCULATE(SUM(FactSales[SalesAmount])) 

為該度量增加一個分組列FullName,可以看到,這個分組列對度量的上下文進行過濾,使其只能計算每個FullName物件的銷售額,而度量自動應用篩選之後的上下文,計算每個FullName的銷售額:

FullName是DimCustomers表的欄位,該欄位能夠自動過濾FactSales表的原因是在資料模型中,表DimCustomers和表FactSlaes之間存在關係,並且關係的方向是由DimCustomer指向FactSales,這說明,DimCustomers可以過濾FactSales:

2,關係的方向

當關系的方向是由A指向B時,說明A可以篩選B,而B不能用來篩選A。上圖中,表DimCustomers和表FactSlaes之間存在關係,並且關係的方向是由DimCustomer指向FactSales,這說明,DimCustomers可以過濾FactSales。我們來測試一下,FactSales是否可以篩選DimCustomers?建立一個新的度量,測試使用FactSales的ProductKey來統計使用者的數量:

Measure CountCustomer = CALCULATE(COUNT(DimCustomers[CustomerKey])) 

測試的結果是 Measure CountCustomers的值是DimCustomers表的總數量,也就是說,ProductKey不能過濾DimCustomers表。

當把DimCustomer和FactSales之間的關係修改為雙向時:

用於FactSales可以過濾DimCustomers,DAX自動應用篩選上下文,統計每個ProductKey對應的客戶數量:

3,修改、清除和重定義篩選上下文

使用DAX函式可以修改、清除和重定義篩選上下文。CALCULATE()函式是DAX中最複雜的函式,用於計算由指定過濾器修改的上下文中的表示式。
CALCULATE(<expression>,<filter1>,<filter2>…) 

 第一個引數是用於計算聚合值的度量,後面的引數是可選的過濾器,共有兩種型別:

  • 返回布林值的邏輯表示式
  • 返回表的表示式

CALCULATE函式的複雜之處在於可變的資料上下文。如果資料已被過濾,則CALCULATE函式會更改過濾資料的上下文,並在您指定的新上下文中計算表示式。 對於filter引數中使用的每個列,將刪除該列上的任何現有過濾器,並應用filter引數中使用的過濾器。

 

 

參考文件:

【DAX聖經】第四章:理解計算上下文(1)

詳解CALCULATE系列-基礎篇

相關文章