DAX是一種專門用於計算資料模型的業務公式的語言,本文以Power BI的關係來學習資料模型。
一,理解資料模型
資料模型是由一組表和關係構成的結構,表和表之間由關係連結,如下圖所示的產品資料模型:
表格是組織資料的二維結構,由行和列構成,其本身是一個最簡單的資料模型。當要描述更復雜的資料模型時,就需要使用多張表。在具有多個表的資料模型中,表和表之間的資料具有關聯性,通過關係把相關聯的兩個表連線起來,並設定關係的型別和方向。
關係用於連線兩個表,是資料模型的重要組成部分,關係具有以下幾個特點:
- 用來建立關係的列(通常在兩個表中都有相同的名稱)被稱為關係的鍵。
- 在表格資料模型中,關係只能在單列上建立。多列關係不被引擎支援。
- 關係的型別有兩種:一對一(1:1),一對多(1:*)。
- 根據關係的型別,關係兩端的表承擔的角色是不同的,在一對多關係中,1端稱為關係的一方,多端稱為關係的多方。
- 在關係的一方,關係的列是表的主鍵,值是唯一的。在關係的多方,關係的列在多方表中允許存在重複值。
- 在每一個關係中,都有一個或兩個小箭頭。箭頭指示自動過濾關係的方向。
- 關係按照方向可以形成一個鏈條,在鏈條上可以對資料進行過濾。
二,理解關係
關係有兩個屬性:型別和方向,在Power BI中,建立的關係需要指定關係的型別(Cardinality)和關係的方向(Cross filter direction),如下圖所示:
1,關係的型別
關係的型別有兩種:1對1,1對多:
- 1對1 :表示關係兩端的列都是唯一列,不存在重複值;
- 1對多 :表示關係兩端的列,1方是唯一列,不存在重複值;而多方的列允許存在重複值。
關係的型別是由關係兩端的列值的唯一性決定的,當列值是唯一時,該端是“1方”,當列值允許存在重複值時,該端是“多方”。
注:PowerBI支援多對多關係。
2,關係的方向
在關係中,箭頭的方向就是關係的方向,箭頭指示在應用關係時對值進行自動過濾的方向。在Power BI中,關係的方向有Single和Both兩種,分別表示單向和雙向。
每一個關係都有一個或兩個方向的過濾,過濾總是從關係的一方到多方。如果關係是雙向的(也就是說,它有兩個箭頭),那麼過濾也會從多方到單方。
關係的方向跟計算的上下文有很大的關係,對CALCULATE()函式計算的結果影響非常大。
三,理解關係的工作方式
SQL查詢和DAX之間存在很多的相似性,SQL和DAX之間最明顯的區別在於模型中的關係工作方式。
在SQL查詢中,你可以在表格之間設定外來鍵來宣告關係,但是引擎在查詢中從不使用這些外來鍵,除非你對它們很明確。例如,如果你有一個客戶表和一個銷售表,其中CustomerKey是客戶的主鍵和銷售中的外來鍵,那麼你可以編寫一個查詢:
SELECT c.FullName as CustomerName, SUM ( s.SalesAmount ) AS SumOfSales FROM dbo.FactSales s LEFT JOIN dbo.DimCustomers c ON s.CustomerKey = c.CustomerKey GROUP BY c.FullName order by c.FullName
即使您使用外來鍵宣告瞭模型中的關係,您仍然需要顯式地在查詢中宣告聯接條件。但是,在DAX中,關係是模型的一部分,它們都是外部連線。一旦在模型中定義了,您就不再需要在查詢中指定聯接型別:當您使用與主表相關的列時,DAX在查詢中使用一個自動的左外連線。因此,您可以在DAX中編寫和以上TSQL等價的查詢:
SumOfSalesTable = SUMMARIZE ( FactSales, DimCustomers[FullName], "SumOfSales", SUM (FactSales[SalesAmount]) )
在DAX中不需要像TSQL那樣顯示指定連線的條件,DAX根據FactSales表和DimCustomers表之間關係,推斷出銷售和客戶之間的關係,自動跟隨模型計算出按照FullName分組後每個客戶的所有訂單總額。
對SUMMARIZE()函式做一個小結:
結論1,主表和相關表的連線是左外連線
FactSales是主表,主表和其相關的列使用左外連線,這就意味著,如果主表FactSales中插入DimCustomers中不存在值,那麼FullName會顯示為Blank。
我做了個實驗,向FactSales表中插入一個無效的CustomerKey:
在重新整理PowerBI的FactSales表之後,發現DAX中的FullName列多了一個空值:
結論2,主表是多方
在SUMMARIZE函式連線兩個表時,主表是多方。
參考文件: