舉個例子,體育場排座位,東南西北四個區、每個區10排、每排20個座位:
笛卡爾集,就是不重複的區、排、座排列好。
在DAX中能夠生成笛卡爾集的函式三個CROSSJOIN、GENERATE、GENERATEALL。
CROSSJOIN函式:CROSSJOIN函式最適合解決排列問題,如果要同時計算其他列的值,可以配合ADDCOLUMNS函式,所以大家會經常看到ADDCOLUMNS+CROSSJOIN這樣的組合。
CROSSJOIN函式中支援多個表的笛卡爾集排列,引數可以是表,也可以是生成表的表示式,所以我們又常常看到CROSSJOIN+VALUES這樣的組合,或者CROSSJIN+DISTINCT組合:
我們之前講過VALUES與DISTINCT函式功能相同,DISTINCT函式要更強大一些,因為引數支援表、列、或者生成表、列的表示式。
引數的型別,決定了函式的適用範圍,比如SUM函式只支援實體表的列作為引數,所以不要試圖將度量值或者計算過程中虛擬表的列傳遞給SUM函式。
GENERATE函式GENERATE函式只支援兩個表生成笛卡爾集,引數同樣支援實體表與生成表的表示式:
GENERATEALL函式與GENERATE函式相同的用法,之處是返回的結果不同,體育場有5個VIP席位,我們把這個表合併到剛才的排座位表格裡:
產生的新表為合併:
我們重新來做排列,我們將排座位中的排與區排列:
因為在排座位表中的行沒有V1排,也沒有VIP區,所以就會顯示空,如果我們用GENERATE函式這一行就不會顯示,這是這兩個函式的主要區別:
另外要注意的是這裡RELATEDTABLE函式的組合,如果我們不使用RELATEDTABLE函式,那麼GENERATE、GENERATEALL函式就相當於簡版的CROSSJOIN函式,只支援兩個引數的CROSSJOIN函式:
只是簡單地用兩個表生成笛卡爾集。RELATEDTABLE函式建立了兩個表之間的篩選關係,然後根據篩選關係來做笛卡爾集。
以上三個函式是表之間建立笛卡爾集,我們常用到的SUMMARIZE函式,也能建立笛卡爾集,不過SUMARIZE函式,更多用在資料分組的時候使用,例如我們統計VIP席位數量:
實際上建立的是區與排的笛卡爾集,然後在這個篩選的基礎上進行計數。
笛卡爾集是完全排列,我們如果要對資料進行分類彙總的時候,就會用到這種方法,比如某種產品有一級分類與二級分類,我們在不確定具體哪個分類沒有銷售的情況下,就可以直接建立一個笛卡爾集,對每一種分類組合進行統計。
今天講的CROSSJOIN、GENERATE、GENERATEALL函式以及SUMMARIZE函式都是能夠建立笛卡爾集的函式,這幾個函式都是常用函式,無論是度量值書寫,還是DAX查詢都經常用到。