表連接是指兩張表根據關聯字段,組合成一個數據集。表連接不僅可以利用數據模型中已有的關系,而且可以利用DAX表達式基於表的任意列定義連接條件。因此,在DAX中,實現表與表之間的連接,有兩種方式:
- 第一種方式:利用數據模型中的現有關系,以便查詢包含在不同表中的數據。
- 第二種方式:編寫 DAX 表達式創建連接,以生成與關系等效的效果。
一,利用數據模型中的關系(左外連接)
利用數據模型中的關系來連接表,是DAX中最常用的行為,關系隱式實現外連接(LEFT JOIN)。DAX數據模型中的關系分為三種:實線關系,虛線關系和虛擬關系。其中,實線關系是指已經創建的、處於激活狀態的關系;虛線關系是指已經創建的、處於未激活狀態的關系;虛擬關系是指未創建、只在DAX中臨時創建的關系。 數據模型中的關系,要求一方提供唯一值列,因此,只能創建1:M 和 1:1類型的關系,當兩個表之間存在多對多的關系時,可以在DAX中使用TREATAS函數創建臨時的關系。
例如,FactSales和DimProduct、FactSales和DimDate之間存在多對一的關系,可以利用關系來建立左外連接(LEFT OUTER JOIN),注意,左外聯接的左表(保留表)是FactSales,右表是DimDate和DimProduct,這意味着,如果FactSales表中存在的數據不包含在DimProduct或DimDate表中,那么這些數據行都被分到Color為空值(BLANK)或CalendarYear為空值的分組中。
SUMMARIZE(FactSales,DimProduct[Color],DimDate[CalendarYear],"SalesAmount",SUM(FactSales[SalesAmount]))
該DAX表達式等價於以下TSQL腳本,
select p.Color ,d.CalendarYear ,sum(f.SalesAmount) as SalesAmount from FactSales f left join DimProduct p on f.ProductKey=p.ProductKey left join DimDate d on f.DateKey=d.DateKey group by p.Color ,d.CalendarYear
二,利用DAX實現自然連接
自然連接不需要指定連接條件,兩個表自動根據同名列進行匹配,前提是同名列的數據類型必須完全相同。在連接期間使用嚴格的比較語義,沒有類型兼容和強制轉換,例如,1不等於1.0。
NATURALINNERJOIN(<leftJoinTable>, <rightJoinTable>) NATURALLEFTOUTERJOIN(<leftJoinTable>, <rightJoinTable>)
這兩個函數不要求兩個表之間存在關系,但是要求兩個表之間存在同名列,並且同名列的數據類型必須完全相同。返回的數據集包含兩個表中的同名列和其他列的數據,如果是自然內連接,那么結果集指包含匹配的數據;如果是自然左外連接,那么左表中的數據會全部保留,右表只返回匹配的數據,對於左表中沒有匹配的數據,把相應的右表列設置為空值(BLANK)。
三,創建虛擬連接
TREATAS函數用於建立虛擬關系,適合在表和表之間不存在關系時使用:
TREATAS(table_expression, <column>[, <column>[, <column>[,…]]]} )
參數注釋:
- table_expression:返回表的表達式
- column:基礎表中的列,不能是表達式,column參數的數量必須和table_expression列數相同,並且順序相同。
返回值:
返回一個表,包含column參數和table_expression參數中匹配的數據行。如果column參數中不包含table_expression中的值,那么忽略該值,也就是說,column參數和table_expression參數使用inner join,只有兩方都存在值時,才會返回該值。
例如,表構造器{"Red", "Green", "Yellow"} 創建一個單列三行的表,在DimProduct[Color]列上設置了一個過濾器,過濾器的值只包含“Red”,“Green”和“Yellow”,如果DimProduct [Color]中不存在“Yellow”,則有效濾波器值將為“Red”和“Green”。
TREATAS({"Red", "Green", "Yellow"}, DimProduct[Color])
TREATAS的應用場景,TREATAS()函數用於在表格之間建立虛擬連接,當表之間出現多對多的關系時,此時無法使用關系來建立連接。
例如,在模型中,表DimProduct1 和 DimProduct2之間沒有關聯,通過TREATAS()函數建立兩者之間的連接:
CALCULATE(
SUM(Sales[Amount]),
TREATAS(VALUES(DimProduct1[ProductCategory]), DimProduct2[ProductCategory])
)
四,激活已有的不活躍關系
在引用關系時,DAX可以在查詢上下文中臨時修改關系的設置,比如引用處於不活躍狀態的關系,修改現有關系的交叉過濾的方向設置。重寫的關系設置只在查詢時有效,不會影響數據模型中的關系設置。
USERELATIONSHIP使用數據模型中已有的關系,用於激活候選關系,通過關系兩端的字段來指定關系:
USERELATIONSHIP(<columnName1>,<columnName2>)
在USERELATIONSHIP函數中,關系的狀態是不重要的,但是關系必須事先創建於數據模型中,由於活躍的關系在DAX中是可以直接引用的,因此,該函數實際上用於引用處於不活躍(Inactive)狀態的關系。
=CALCULATE(SUM(InternetSales[SalesAmount]), USERELATIONSHIP(InternetSales[ShippingDate], DateTime[Date]))
五,指定交叉過濾的方向
CROSSFILTER 使用數據模型中已有的關系,通過關系兩端的字段來指定關系:
CROSSFILTER(<columnName1>, <columnName2>, <direction>)
在CROSSFILTER 中,關系的交叉過濾(cross-filtering)的設置是不重要的,也就是說,不論關系在數據模型中設置為single 方向或both方向,都不會影響函數的使用,CROSSFILTER將覆蓋任何現有的交叉過濾(cross-filtering)設置。
參考文檔: