Power BI中的度量值、計算列和計算表

什麼是計算列、什麼是度量值

計算列是直接在現有的表上添加一個新列,

新建的計算列,和表中之前已經存在的列一樣,可以作爲表格的行、列,圖表的軸以及切片器的字段等等,也可以使用計算列與其他表建立關係。

度量值,如果不放到上下文環境中,它就是一個孤立的公式,並沒有視覺上的計算結果,因此,很多人會覺得度量值比較難以理解,尤其是Excel用習慣的人,都會傾向於使用計算列。

字段標識不同

如下圖的字段面板

倒數第二個字段,前面有fx符號,代表的是計算列;而最下面一個,前面是個計算器的標識,表明[最後訂單日期]是一個度量值。

怎麼寫計算列、怎麼寫度量值?

這個纔是大家更關注的問題,也是平時容易出錯的地方。下面以一個實例來介紹計算列與度量值的寫法有什麼不同。

以這個簡化的訂單表爲例,如何計算出每個客戶的最後下單時間?

計算列的寫法

不少人也許直接這樣寫,

結果都是訂單表中最後一個訂單日期,顯然與我們的期望不符,爲什麼會這樣呢?

計算列的上下文就是當前行,但是MAX函數(包括SUM、MIN等聚合函數)並不能將行上下文轉化爲篩選上下文,也就是說當前行沒有起到篩選作用,它就會返回整個表的最大訂單日期。

關於上下文,不要理解的太複雜,完全可以按中文字面意思來理解,簡單來說就是當前的計算環境,一般分爲行上下文和篩選上下文,行上下文可以簡單的理解爲當前行,行上下文並不會必選產生篩選作用,只有篩選上下文才會產生篩選作用,篩選上下文有很多種形式,比如表格的當前行,矩陣的行和列、圖表的座標軸、報表的切片器、篩選器等。

如何讓當前行發生篩選作用呢?在MAX函數外圍再套個CALCULATE函數就可以了,

這樣返回的下單日期都不同了,但是仔細看就會發現,返回的日期和當前行的下單日期是一樣的,並沒有按照客戶進行計算。

再強調一遍,計算列的上下文就是當前行,包括當前行的每一個值,在上表中,每一行的數據是唯一的,因此只能返回當前行的訂單日期。

那麼到底如何按照客戶來計算,返回當前客戶的最後下單日期呢?

解決這個問題的DAX寫法有很多種,這裏用個相對簡潔的代碼,

ALLEXCEPT函數的意思是,清除訂單表其他列的篩選作用,只保留客戶列的篩選,這樣當前行的上下文,其他列的篩選作用清除了,只有客戶發生篩選作用。

比如客戶甲,有兩筆訂單,使用MAX計算出最大的訂單日期,也就是甲的最後下單日期。

上面說了這麼多計算列的寫法,那麼度量值該怎麼寫呢?

最後下單日期=MAX('訂單表'[訂單日期])

是不是簡單到不敢相信,那麼如何看到計算結果呢,最簡便的方式就是直接用個表格或者矩陣展現結果,

再舉個例子,依然是這個訂單表,如何計算每個產品的最後賣出日期?

如果你理解了上面計算列的原理,這個問題是不是也很容易就出來了,

那麼度量值又是如何寫才能解決這個問題的呢?

其實度量值的寫法可以完全不變,依然可以用上面的代碼(MAX('訂單表'[訂單日期]),只要把表格的維度改爲產品名稱就可以了,

通過上面兩個問題,你看出來計算列和度量值有哪裏不同了嗎?

在計算列中,其上下文是明確的,就是當前行,並且可以根據需要縮小爲當前行的某一列;

而度量值,編寫時並沒有明確的上下文,度量值寫好之後,可以放在任意的上下文環境中,執行不同的計算;

計算列寫好代碼,數據自動計算出來,並且不受外部篩選器的影響;

而度量值寫好之後,並沒有立即計算,只有放到上下文中時,才進行計算並返回結果。

所以利用DAX解決問題時,首先應想到上下文是什麼,新建列時如何利用當前行的上下文?

而度量值雖然暫時沒有上下文,但在建度量值之前,也首先應該想清楚,我需要構建怎樣的上下文環境才能得到期望的結果,然後利用心中所想的上下文環境,來對應的編寫度量值的DAX代碼。

在PowerBI中,除了計算列和度量值,還有個地方可以用到DAX,就是使用DAX新建表,

使用建表的方式同時可以解決上面的問題,

其中VALUES('訂單表'[客戶]),返回客戶的不重複列表,就是爲了給後面的代碼提供上下文,有了這個上下文,後面的代碼與新建列的寫法是一樣的。

通過這三種使用DAX的環境,以及上面的幾個例子,應該能發現,無論是度量值、計算列還是建新表,其DAX代碼本質上並沒有什麼不同,不同的只是下上文而已。

計算列只能利用當前行上下文;新建表可以使用DAX構建上下文;’而度量值最靈活,先不管上下文,寫好代碼之後,給什麼上下文,就執行什麼運算,或者說需要什麼計算,就給度量值提供什麼上下文。

你以後再遇到問題打算用DAX實現,一定要先想清楚,是通過計算列、新表還是度量值來解決,然後再開始寫對應的DAX。

計算列和度量值寫法的不同點

關於計算列和度量值在寫法上有一些不同,比如在計算列中使用列,可以直接使用,默認就是該列的當前行,比如返回當前訂單日期的前一天,可以直接寫:

而在度量值中使用列,必須在列上套一個聚合函數,否則不能自動轉換爲篩選上下文,計算訂單日期前一天的度量值應該這樣寫:

訂單日期前一天 = MAX('訂單表'[訂單日期])-1

什麼時候使用新建列,什麼時候使用度量值

一般來說,爲了性能考慮,能用度量值解決的問題就儘量不用計算列(參考:高效使用Power BI的15條建議)。

只有當你需要利用新建的計算列生成切片器(度量值不能用於切片器),或者需要用這個字段與其他表建立關係時,才需要新建列。

另外當需要創建很複雜的字段時,儘量使用計算列,因爲它需要時間來運算,提前運算完成,而不是在需要用的時候再進行計算(度量值是用的時候才計算),可以帶來更流暢的體驗。

總結

計算列和度量值在DAX代碼的寫法上並沒有本質不同,形式上的不同只是由於上下文環境的區別引起的。

二者的本質不同在於其運算特點,是否根據上下文動態運算、以及計算時間上的不同,纔是根本的差異。



《PowerBI商業數據分析》上市了

-精彩推薦-

PowerBI數據分析和可視化實戰案例

Power BI商業數據分析模型:RFM客戶價值分析

如何用PowerBI 打造高大上的財務報表分析報告?

採悟 from PowerBI星球

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章