DAX語言入門介紹-封面

DAX語言入門介紹,第一次學必看!

DAX是Data Analysis Expression的縮寫(以下稱DAX),為Excel及Power BI所用之資料分析語言,資料分析語言聽起來較深奧,其實就是Excel中樞紐分析表撰寫量值(Measure)的公式,以及Power Pivot(資料模型)裡增加資料行的公式;DAX由Excel公式演變而來,但不像Excel公式可以隨意參照儲存格,DAX分析的對象為資料模型,所以較Excel撰寫儲存格公式多了許多限制及有著更深一層的資料分析概念,本篇文章將針對DAX基礎概念進行介紹

DAX使用目的

DAX主要運用於商業智慧(Business Intelligence,簡稱BI)上,所以DAX使用目的簡單來說就是:利用DAX針對公司各機能資料模型進行Q&A資料分析,以幫助公司找出有利的經營方針。

下圖為資料模型示意圖,還不了解資料模型的人可先閱讀此文章Excel資料模型入門介紹

20220730_P1

資料分析Q&A可以有千百種,以下列舉幾個例子:

「2022年度哪一個商品的銷售量最佳?買量最大的客戶是哪一家?」

「針對iPhone 13 Pro商品,2022年度哪一個季節銷售量最佳?哪一種顏色銷售量最佳?

iPhone 13 Pro及Galaxy Z Flip3 5G手機的銷量於2022年度手機市場銷售量的佔比?購買者年齡層於青年、壯年、中年、老年人的分布情形?」

「請表列2022年各月份各商品的營業收入、營業成本、毛利率與淨利率,並與2021年做比較。

「請找出2022年度哪些商品的毛利率<10%,並對其做進一步的成本分析。」

請製作2018~2022年某公司各產品線的損益趨勢圖。

學完DAX與資料模型後,基本上就可以回答得出以上Q&A。

但若撰寫DAX的目的只以Q&A說明,相信大部分的讀者還是會覺得有點抽象,大家應該會問:

「那要以什麼方式回答Q&A的問題呢?」

回答Q&A呈現的方式不外乎就是報表及儀表板,以下將針對Excel與Power BI回答Q&A的方式進行說明。
(本站的儀表板展示間可體驗互動式報表)

1.Excel

於Excel中,係以資料行(Calculated Column)及量值(Measure)的方式撰寫DAX,將資料模型內的資料進行集計(Aggregate)計算,並利用樞紐分析表(PivotTable)、樞紐分析圖表(PivotChart)或其他Excel圖表等功能,將報表與儀表板呈現於Excel工作表中(Sheet)。(範例如下圖,分析視角為每月30天)

20220730_13_1

2.Power BI

於Power BI中(Power BI入門介紹),係以資料行(Calculated Column)、量值(Measure)及資料表(Table)的方式撰寫DAX,將資料模型內的資料進行集計(Aggregate)計算,並利用視覺化物件(Visualizations)的功能,將報表與儀錶板呈現於Power BI報表(Report)檢視頁面中。(範例如下圖,分析視角為月份)

20220730_14

Power BI較Excel多了資料表(Table)的撰寫DAX方式,總共3種撰寫DAX的方式將於下一節中詳細說明。

文章讀到這邊大家可能還覺得DAX是個很有趣的主題,BI好好玩...,但實際上DAX的學習之路可能會讓大家遭遇到不少挫折,但請大家不要氣餒,這都是正常的過程,要學好DAX必須經過反覆的思考、練習,及配合看書、上課,小編就在此幫大家起個頭,歡迎來到資料分析與BI的世界。

撰寫DAX的3種方式

1.資料行(Calculated Columns)

資料行一詞本篇文章將統一以Calculated Column稱呼,資料模型的資料表的Calculated Column其實與Excel資料表(Table)資料欄的特性相近(可參考此篇文章介紹Excel資料表),以Calculated Column撰寫公式時,係以列為單位去計算不同的欄位,例如撰寫一個銷售額的Calculated Column,公式=
'Sales'[銷售額] = 'Sales'[Quantity] * 'Sales'[Unit Price],那日期5/29的銷售額就會是5/29的銷售量乘以5/29的單價,不會是5/29的銷售量乘以5/30的單價。(如下圖)

20220730_P9

於Excel與Power BI裡加入Calculated Column的方式簡單說明如下。

Excel中撰寫Calculated Column的方式:

20220730_P2

Power BI中撰寫Calculated Column的方式有兩種:

20220730_P3

或:

20220730_P7_1

Calculated Column使用目的是「於資料模型的資料表中補充資料分析時會利用到的資料欄位」,大家還記得建造資料模型的流程圖嗎(如下圖),資料模型是將數個資料表之間建立關聯性,例如原本銷售資料表(Sales)裡面沒有單價的欄位,但可以利用關聯性從產品資料表(Product)中取得單價,如下下圖公式:
'Sales'
[Unit Price] = RELATED('Product'[Unit Price])
然後就可以利用這個新欄位(Calculated Column)去計算銷售額。

20220601_P2-2
20220730_10

還有一個很常用的使用Calculated Column情況是:輔助資料模型進行篩選資料的欄位,例如設定一邏輯:銷售量<1000顯示A、>=1000顯示B,然後在報表中就可以A或B來快速篩選資料。(如下圖)

20220730_P4

綜上所述,各位可以把Calculated Column想成是一個輔助者的角色,主要撰寫DAX以回答商業智能Q&A的方式為量值(Measure)等等馬上介紹。另外,因Calculated Column儲存於資料模型的資料表中,所以若大量使用Calculated Column或使用公式複雜的Calculated Column會影響到資料模型重新整理時的效能。

2.量值(Measure)

量值一詞本篇文章將統一以Measure稱呼,Excel與Power BI主要皆以撰寫Measure方式來分析資料,Measure有別於Calculated Column,Measure不屬於某個資料表,它存在於資料模型中,在寫DAX時係以某一個資料表數據做為主體(出發點),並搭配其他資料表(維度)去進行資料分析。

Measure與Calculated Column加入報表的方式也有差別,以Excel為樞紐分析表為例,一般若將Calculated Column拉入樞紐分析表的數值(Values),樞紐分析表會自動(強迫)將此Calculated Column加上一個摘要值(Summarize)方式(如SUM、AVERAGE...等),但若是將Measure拉入樞紐分析表則不會被加上摘要值,大家可以把Measure想像為一個資料分析、集計(Aggregation)的邏輯,此邏輯可以取代掉樞紐分析表預設的摘要值方式,故在將Measure拉入樞紐分析表的數值(Values),及將資料模型中不同維度的資料欄位拉入樞紐分析表的列(Row)、欄(Column)或篩選(Filter)後,就可以進行相當豐富及有意義的資料分析。(若對樞紐分析表不熟悉的讀者可以先參考先前的文章樞紐分析表概念介紹)

另外,還可利用一個Measure去撰寫另一個Measure(例如引用一個銷售額的Measure去寫一個新Measure,並加入時間函數,就可以變成例如上月銷售額的Measure),亦可較Calculated Column節省許多儲存空間。

於Excel與Power BI裡撰寫Measure的方式說明如下。

Excel中撰寫Measure的方式有兩種:

20220730_P5

或:

20220601_P11

Power BI中撰寫Measure的方式有兩種:

20220730_P6

或:

20220730_P8_1

3.資料表(Table)

此功能目前僅有Power BI可使用,係指利用撰寫DAX來創造一個新的資料表(範例如下圖),其概念亦是後端資料庫Query的概念。因此功能較為進階,後續有機會再於其他文章中進行介紹。

20220730_11

DAX集計子(aggregators)與疊代子(iterators)

集計子(以下稱aggregators)係為執行集計(以下稱aggregate)行為的函數,那什麼是aggregate呢?aggregate原是指後端資料倉儲(Data Warehouse)中從資料蒐集(Collect)→資料處理(Process)→到資料摘要值(Summarize)的一個過程,於Excel及Power BI資料模型中其實也有類似的概念,各位讀者僅需簡單記憶為aggregate = summarize就好。
PS 摘要值(Summarize)一詞用於Excel樞紐分析表中。(如下圖)

幾個大家熟悉的SUM、AVERAGE、MAX與MIN函數皆為aggregators。aggregators函數的主要參數為資料欄(Column),亦即是針對一整個欄位進行計算。

20220709_P13

疊代子(以下稱iterators)大家應比較陌生,iterators係為執行iterate行為的函數,那什麼是iterate呢?iterate可以比喻為掃描(SCAN)的行為,是指將資料表進行一列一列的逐一掃描(就像是程式語言中的迴圈行為For....Next);因為iterators函數會先掃描完資料表後再進行數據集計(Aggregate),所以可藉由篩選資料表來改變計算的結果(等會兒範例說明)。

一般常用的iterators函數很好記,就是在aggregators後面加一個X就變成iterators,例如SUMX、AVERAGEX、MAXX、MINX等,另有一些沒有加X也常用的iterators順便記一下,如FILTER、ADDCOLUMNS、SUMMARIZE等

iterators函數主要有兩個參數:(1)資料表及(2)計算式。

以下兩個Measure範例中,可以清楚看出有無使用iterators的差異:
(1)銷售量 = SUM('Sales'[Quantity])
(2)產品1的銷售量 = SUMX(FILTER('Sales', RELATED('Product'[Product Category])=
"產品1"),'Sales'[Quantity])
各位可以發現Measure(產品1的銷售量)只有顯示出產品1的銷售量(如下圖),這就是iterator(SUMX)受到資料表的篩選而影響到計算結果;而Measure(銷售量)因為是使用aggregator(SUM),無法改變其計算的資料表,故顯示出全部產品的銷售量。

20220730_12

DAX的兩種評估環境(Evaluation Contexts)

本節將介紹DAX的評估環境(以下稱Evaluation Contexts),Evaluation Contexts的觀念很重要,因為所有DAX計算都是先進行Evaluation Contexts之後才進行計算,DAX中Evaluation Contexts有兩種,包含(1)篩選環境(Filter Context)及(2)列環境(Row Context),因一個資料格(Cell)中可以同時存在篩選環境(Filter Context)及列環境(Row Context),許多人常常搞不清楚他們的差別,所以在開始介紹之前先唸一段口訣給各位,大家記一下:

「The filter context filters the model, whereas row context iterates tables」
意思為篩選環境是對整個資料模型做篩選,而列環境是針對資料表進行疊代(掃描)。

以下將分別進行介紹

1.篩選環境(Filter Context)

篩選環境(以下稱Filter Context)一般是由報表(儀錶板)的設定來決定,以Excel樞紐分析表為例,Filter Context包含了樞紐分析表中的列(Row)、欄(Column)、篩選(Filter)及篩選器(Slicer)。我們要分析的數據會在這幾種Filter Context的篩選下被切割開來,呈現出有意義的數據。

以下圖為例,各位可以看到下圖目前不存在Filter Context,樞紐分析表中僅有數值(Values)欄位為"銷售量"。

20220730_15

當我們將"產品類別"拉入樞紐分析表的列(Row)、"月份"拉入欄(Column)、"客戶名稱"拉入篩選(Filter)及"年份Year"拉入篩選器(Slicer)之後,"銷售量"數據在這4種Filter Context篩選下,被分割成有趣的數據。(如下動圖及下下圖)

20220730_G1
20220730_16

另外,各位讀者想一想在列與欄合計的交集處數據中,Filter Context是什麼?(如下圖紅色框框處)

20220730_17

答案是"客戶名稱"及"年份Year",因為在合計欄交集處是不受"產品類別"及"月份"Filter Context篩選的。

Filter Context概念先介紹到這裡,接下來介紹列環境(Row Context)。

2.列環境(Row Context)

列環境(以下稱Row Context)係指DAX計算時以資料列為單位一列一列得去計算,Row Context使用目的包含:
(1)若需先以資料列與資料列之間進行計算後再進行集計(Aggregate)的狀況,例如在計算總銷售額時,會先計算每一列的銷售額'Sales'[Quantity] * 'Sales'[Unit Price]後,再進行加總。
(2)需利用資料列的數值作為DAX計算時的計算條件,例如計算銷售量累積值時,會設定一個篩選條件為「將小於此資料列(日期)的所有銷售量進行加總」,如此每一資料列的累積值會不一樣,符合我們想要的結果。此兩個應用等等皆會再進行細部說明。

那要如何產生Row Context呢?產生Row Context的方式包含兩種:
(1)使用Calculated Column就會有Row Context,因為Calculated Column本身資料欄的特性,就會自帶Row Context。
(2)使用iterators,大家還記得上一節說的疊代子(iterators)嗎?iterators的特性會先掃描資料表後,再針對此資料表一列一列得去計算公式,最後再進行集計。

範例一:(計算銷售額)

此範例以Measure方式撰寫DAX,利用iterator(SUMX)產生Row Context,先一列一列地計算每一資料列的銷售額(銷售量乘以單價)後,再進行加總。
=SUMX('Sales',Sales[Quantity]*Sales[Unit Price])

20220730_19

範例二:(計算累積銷售量)

此範例以Measure方式撰寫DAX,利用iterator(FILTER)產生Row Context,計算銷售量年累積值時,一列一列地將小於疊代當下最大日期的所有銷售量加總(此最大日期會取決於報表設定的Filter Context,此範例報表的Filter Context是2021年及月份,那2021年1月份的最大日期就是2021/1/31、2021年2月份的最大日期就是2021/2/28,以此類推),及疊代時亦考量到報表Filter Context的最小日期(2021/1/1),此兩個條件下,2021年1月份的Filter Context為2021/1/1~2021/1/31,2021年2月份為2021/1/1~2021/2/28,以此類推,可計算出各月份的年累積值。
=CALCULATE(SUM(Sales[Quantity]),
FILTER(ALL('Calendar'),'Calendar'[Date]<=MAX('Calendar'[Date])))

此範例所用的CALCULATE是DAX中唯一可以產生Filter Context或改變既有Filter Context的函數,功能強大,觀念較深,讀者可參考CALCULATE函數入門介紹文章。

20220730_P20
20220730_P21

Row Context概念先介紹到這裡。

總結及補充:

相信大家讀到最後應該有點頭暈,DAX難學的地方就在於要搞清楚這幾個名詞定義及了解資料是在什麼樣的評估環境下進行計算的,本篇文章所提的相關名詞包含:資料行(Calculated Column)、量值(Measure)、集計子(Aggregators)、疊代子(Iterators)、評估環境(Evaluation Contexts)、篩選環境(Filter Context)及列環境(Row Context)。

幾個容易混淆的觀念再摘要說明一次,DAX撰寫的方式主要有Calculated Column及Measure兩種,其中:
Calculated Column會自帶Row Context,將資料逐列計算,使用Calculated Column的目的主要為增加資料欄以輔助資料分析;撰寫DAX進行資料分析的主要方式為Measure,Measure若要產生Row Context需要使用iterators函數(如SUMX、AVERAGEX等)。
另外Filter Context一般來自報表(儀錶板)的設定(如樞紐分析表中的列、欄、篩選及篩選器),唯一可以產生或改變既有Filter Context的函數為CALCULATE。

兩種評估環境差異的口訣再複習一次:
「The filter context filters the model, whereas row context iterates tables」
篩選環境是對整個資料模型做篩選,而列環境是針對資料表進行疊代(掃描)。

最後,若大家有興趣自己研讀DAX,推薦一本DAX聖經給大家(Amazon連結),由Marco Russo及Alberto Ferrari先生所撰寫的書The Definitive Guide to DAX。

20220730_20

這篇文章對您有幫助嗎?

平均評分 4.5 / 5. 8

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?

發表迴響