https://zhuanlan.zhihu.com/p/79522456
對於PowerBI使用者而言,經常碰到的一個問題是,想把度量值放到坐標軸上,卻發現無法實現。尤其是初學者,更是習慣性的想這么做。
PowerBI星球嘉賓天行,摸索出了一個解決該問題的思路,請慢慢品讀吧。
解決度量值不能作為坐標軸字段的問題
作者:天行
初入Power BI的門,很快就會被度量值和計算列的動態性吸引,進而義無反顧地跳進DAX的火坑中,然后……(省略號的內容留給曾經在坑中和正在坑中徘徊的各位自行填寫吧 )
如何將度量值作為圖表的軸,這是使用Power BI解決實際問題時繞不過去的“坑”之一,而這個問題常常是由對某類數據進行分類,然后需要對分類的情況進行統計時產生的。
正好星球中的米妮黃同學在群中提到一個關於課程學習動態評價的問題,本文就借與她探討解決問題的示例,來一次性說清楚解決度量值作為圖表軸的字段思路原理,方便大家舉一反三,解決工作中類似的實際問題。
一、示例描述
基本情況:一批人參加多門課程學習,評價是否通過的標准為學習課程的門數。
解決要求:評價標准是動態的,根據動態評價標准(學習課程門數)評價每個人的學習狀態,並實時統計這一批人中不同學習狀態的人數。
建一個示例基礎數據表【data】
需求具體化:該表中有11人,通過課程從7門到24門不等,根據動態評價標准,實時統計通過和未通過的人數。
二、解決思路
(1)通過新增計算列的方式解決
1、在【data】表中新增計算列【評價結果 計算列】
即設定通過標准為13,有8人顯示“完成學習”,3人顯示“繼續努力”
2、增加一個度量值【人數累計 評價標准 計算列】統計不同狀態的人數
人數 累計 評價標准 計算列 = COUNTROWS('data')
3、添加一個堆積柱形圖,將【評價結果計算列】作為軸,【人數 累計 評價標准 計算列】作為值,可以呈現“完成學習”和“繼續努力”的分類人數統計。
4、試圖解決動態評價問題:通過【新建參數】功能設定一個動態評價標准。
如上操作后,將自動生成【通過標准】參數表和一個滑桿控件,其中【通過標准】表包含【通過標准】字段和【通過標准 值】度量值。
5、修改【評價標准計算列】公式為
評價結果 計算列 =
IF([通過課程]>=[通過標准 值],"完成學習","繼續努力")
理論上應該可以根據動態調整的評價標准,對每個人進行重新評價。
結果發現盡管滑桿調整后,【通過標准 值】隨之會發生正確變化,但是【評價結果 計算列】的結果始終不變,進一步研究會發現【評價結果 計算列】的判斷標准居然一直是10,好詭異!
至此,通過計算列解決動態評價的問題已宣告失敗,具體原因后面再分析。
(2)通過度量值的方式解決
1、新增【評價標准度量值】,與參數度量值綁定進行是否通過判斷。
評價標准 度量值 =
VAR vMax=MAX('data'[通過課程])
Return
IF(vMax>=[通過標准 值],"完成學習","繼續努力")
2、新增堆積柱形圖,卻發現【評價標准度量值】無法拖放進“軸”里,似乎又進入了死胡同。
下面進入本文的重點,如何解決度量值不能用作圖表軸的問題?
01 | 新建一個過渡表【標准】
02 | 新建三個度量值
03 | 將【標准】表中的【標准】字段拖入堆積柱形圖的"軸"中,將【數量選擇】度量值放入堆積柱形圖的”值“中,可以呈現分類統計人數結果。
04 | 再試着拖動滑桿動態調整評價標准,可以看到每個人的評價結果隨之變化,堆積柱形圖正確呈現每種分類人數的動態變化。
至此,我們另辟蹊徑解決了度量值不能用作圖表軸的問題。

三、原理探討
在解決這個“小“問題的過程中,實際上涉及到DAX的兩個核心問題:計算列的刷新原理和圖表的本質,下面我們結合這個示例來深入探究。
(一)計算列為什么不能根據動態參數進行刷新?
在DAX的設計中,計算列是在數據裝載的過程中進行計算刷新,可以簡單理解為在點擊【主頁】菜單的【刷新】項時,對所有表的數據進行重新裝載,或者重新打開Power BI文件時,計算列才會進行計算,其他時候計算列不會發生變化。
而度量值則是在計算上下文發生改變時,就會實時進行重新計算。
所以,在本例中,動態參數發生改變時,因為【data】表中每個人的學習課程數沒有變化,所以【data】表中的計算列也不會重新計算。
進一步思考可以得出:計算列的原理是數據裝載時一次性計算,主要占用內存資源;度量值是隨着計算上下文的變化實時計算,主要占用CPU資源。
再往深處推演:如果同樣的計算結果,表格中的行數越多,添加的計算列占用的內存將越多,同時報表打開的速度也會因為大量的計算列計算而隨之減慢。
最后可以收獲一條實際工作中的DAX使用原則:明細數據較多時,為保證報表打開效率,盡量使用度量值,而不要使用計算列;如果需要實時調整參數,實時得出分析結果,則只能使用度量值。
(二)圖表的軸到底是什么?為什么度量值不能用作軸?
要理解圖表的軸是什么,首先要理解圖表是什么。
這一點可以通過PowerBI里面的實際操作來得出結論。
選擇堆積柱形圖,進行復制(Ctrl+C)、粘貼(Ctrl+V)操作,得到一個一模一樣的堆積柱形圖復制品,選中“復制品“,在【可視化】面板中切換為【表】,發現”復制品“轉換成了一個普通的二維表。
從這個轉換中,我們可以得出結論:PowerBI的圖表本質就是表格(如果有興趣,可以將每種圖表都轉換一次,看看結果是否一致),圖表只是表格的一種表現形式。
那么為什么度量值不能當作軸呢?這個問題的答案同樣可以通過實際操作推演出來。
新建一個表格,按照開始的思路,把【評價標准 度量值】和【人數 累計 評價標准 計算列】放到“值“中,得出兩個風馬牛不相及的結果:
【評價標准 度量值】是根據沒有【姓名】篩選的情況下所有人課程的合計數去判斷是否通過,結果自然是"完成學習".
【人數 累計 評價標准 計算列】是沒有篩選上下文的的行計數,所以結果是11。
這兩個結果雖然能夠放到一個表格里面,但毫無實際意義,而圖表是要呈現一種數據之間邏輯關系的結果,沒有邏輯關系的度量值當然不能放到圖表的軸里了。
那么這個堆積柱形圖的意義應該是什么呢?
我們從“復制品”轉換成功的表格中可以看到清晰的數據之間的邏輯關系:根據評價標准對數據進行分組聚合運算,得出每種標准的實際人數。
由此,我們已經推演出圖表的核心原理:
1、圖表的本質是表格
2、由於圖表必須呈現數據間邏輯關系的意義,所以必須根據確定的標准(維度)對數據進行分組,然后進行各種聚合運算,這也就是為什么度量值不能作為圖表的軸的根本原因。
既然已經明了圖表的原理,具體解決辦法就是雕蟲小技了。
1、建立一個過渡表,對應每一種可能分類的類型;
2、用過渡表的分類標准字段作為圖表中的軸字段(分組條件)
3、針對每種分類構建一個單獨計數的度量值(【數量繼續努力】和【數量 完成學習】)
4、構建【數量選擇】度量值,通過判斷篩選上下文的分類標准,調用對應的單獨計數度量值,作為圖表的值字段
這是一個解決DAX動態性的小套路,熟練掌握,靈活運用后可以解決很多具體問題。
您掌握了嗎?
后記:
關於度量值不能作為圖表軸字段的問題,曾經被當作PowerBI易用性遠不如Tableau的證據,但是如果在理解了本文的推演原理,掌握了解決問題的套路之后,再回頭看待這個所謂的“證據”,應該是PowerBI在易用性和靈活性之間的當前取舍,所謂度量值可以當軸字段的功能不過是一個過渡表小套路自動化的過程,從最近PowerBI的演進速度和方向來看,也許就在某次月度更新中就會不經意來到我們手邊,讓我們共同期待吧。