https://zhuanlan.zhihu.com/p/101812525
PowerBI中,有三個地方可以使用DAX,分別是度量值、新建列和新建表,這三個功能並成一排擺放在這里,如圖所示,
之前的文章中曾介紹了度量值和計算列的異同(收藏 | Power BI計算列和度量值,一文幫你搞清楚),這篇文章再來帶你認識度量值和新表的異同。
度量值和計算列容易混淆,但和新表好像並不會搞混,畢竟一個是值,一個是表,區別還是很大的。
但在實現特定的業務需求上,他們又都可以實現,下面以一個案例來介紹。
該案例來自知識星球中星友的提問,模擬一個訂單表,包含客戶名稱、產品名稱以及產品類目等,如下圖:
需求:
僅購買過一個產品類目的客戶有哪些?
購買過多個產品類目的客戶有哪些?分別購買了哪些類目?
下面以新建表和度量值兩種方式來實現。
新建表
因為這個需求返回的客戶肯定不止一個,所以很自然的想到用新表的方式。
這個問題的關鍵是先統計出每個客戶購買了幾個類目,然后分別返回購買了一個和多個類目的客戶列表就行了。
用DAX處理很簡單,如下圖,
先使用SUMMARIZE進行統計,然后FILTER返回等於1的表,只有B和C兩個客戶僅購買過一個類目的產品。
同理,購買了多個類目產品的客戶可以這樣寫,
對於購買了多個類目的客戶,還要列出來購買了哪些類目,可以在上面這個代碼的基礎上優化一下:
返回的表正好是需要的效果。
但是通過這種方式返回的客戶列表是固定的,因為它的上下文已經被固化了,無法根據外部的篩選器返回不同的列表。
如果想要動態的實現需求,比如按照日期切片器,計算不同時間段的客戶列表,怎么辦呢?
動態的效果還是要靠度量值。
度量值
這種方式比較直接,只需要建兩個簡單度量值:
類目數量 = DISTINCTCOUNT('訂單表'[產品類目])
類目列表 =
CONCATENATEX(SUMMARIZE('訂單表','客戶表'[客戶],'訂單表'[產品類目]),'訂單表'[產品類目],"、")
這兩個度量值的代碼是不是要比新建表的DAX簡單的多?你可以先思考一下是為什么?
把這兩個度量值放入到矩陣中,客戶名稱作為行標題,就是我們要的效果,
想查看購買過一個類目或者多個類目的客戶列表,使用篩選器就可以了,

並且它也可以動態響應外部篩選器,返回不同的結果,
就是這么簡單。
總結
通過上面的示例,應該可以看出二者的區別,雖然都能返回一個特定的結果,但度量值更有優勢:
代碼更加簡短,因為無需在代碼中指明上下文;
計算更加靈活,因為它可以根據不同的上下文,實現動態的計算。
最根本的區別還是在於上下文,包括之前介紹過的計算列,三者比較,同樣如此。
所以當你有了一個分析需求,想用PowerBI實現時,不要一上來就想DAX怎么寫,用什么函數,而是先梳理自己的需求,審視自己的數據:
- 想要靜態還是動態的效果?
- 是用新建表、計算列還是度量值來實現?
- 不同方式下,能提供的上下文是什么?
- 這個上下文是否有對應的維度表?
- 維度表與事實表是否已經建立了正確的關系?
最終的落腳點還是數據建模!