DAX 第八篇:表連接


表連接是指兩張表根據關聯字段,組合成一個數據集。表連接不僅可以利用數據模型中已有的關系,而且可以利用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)設置。

 

參考文檔:

DAX 聯接表系列(三)

TREATAS

USERELATIONSHIP


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM