白茶在很久之前,寫過關于笛卡爾積的兩個函數。
GENERATE函數與CROSSJOIN函數。
傳送門:《笛卡爾積》
那麼這兩個函數之間具體的差別是什麼呢?在實際用途中的差別呢?
本期白茶來解釋一下二者之間的核心點:上下文傳遞問題。
在微軟的官方介紹中并未提及兩個函數的差別。
但是從文法上看GENERATE參數隻能是兩個,CROSSJOIN參數可以是多個。
但是實際使用上,二者還有一個核心的關鍵點,就是GENERATE函數可以傳遞第一參數的上下文,而CROSSJOIN函數不能傳遞第一參數上下文。
白茶将通過一組案例資料進行說明:
這是白茶随機模拟的資料,将其導入到PowerBI中,建立日期表以及模型關系如下:
編寫如下路徑成本:
GENRATE =
GENERATE (
{ "當月", "當季", "當年" },
SUMMARIZE (
'銷售明細',
'銷售明細'[商品名稱],
"INDEX", SWITCH ( [Value], "當月", 1, "當季", 2, "當年", 3 ),
"資料",
SWITCH (
[Value],
"當月", TOTALMTD ( SUM ( '銷售明細'[銷售數量] ), 'DATE'[Date] ),
"當季", TOTALQTD ( SUM ( '銷售明細'[銷售數量] ), 'DATE'[Date] ),
"當年", TOTALYTD ( SUM ( '銷售明細'[銷售數量] ), 'DATE'[Date] )
)
)
)
複制
結果如下:
這段代碼是什麼意思呢?
1.首先是利用輸入模式,直接輸入了三個時間粒度的辨別字段作為第一參數;
2.然後利用SUMMARIZE函數生成一個表,添加了“資料列”和“索引列”;
3.SUMMARIZE函數利用GENERATE函數傳遞第一參數上下文的功能,根據條件判定進行計算。
這樣的話就對“商品名稱”這一列進行了不同時間粒度的彙總。
動态效果如下:
根據切片器的選擇,可以在表中呈現不同時間粒度彙總的結果。
那麼别忘了,還有CROSSJOIN函數呢。
輸入如下代碼:
CROSSJOIN =
CROSSJOIN (
{ "當月", "當季", "當年" },
SUMMARIZE (
'銷售明細',
'銷售明細'[商品名稱],
"INDEX", SWITCH ( [Value], "當月", 1, "當季", 2, "當年", 3 ),
"資料",
SWITCH (
[Value],
"當月", TOTALMTD ( SUM ( '銷售明細'[銷售數量] ), 'DATE'[Date] ),
"當季", TOTALQTD ( SUM ( '銷售明細'[銷售數量] ), 'DATE'[Date] ),
"當年", TOTALYTD ( SUM ( '銷售明細'[銷售數量] ), 'DATE'[Date] )
)
)
)
複制
與上面的代碼對比,二者除了使用函數差別外,沒有任何差別。
結果如下:
結果無法得出,白茶第一次遇到這個問題的時候,思考了很久,感覺即在意料之外,也在情理之中。
首先是GENERATE這個函數本身隻有兩個參數,那麼進行上下文傳遞的時候,可以說已經被劃定範圍了,這樣的話雖然代碼計算的速度慢,但是會有結果。
而CROSSJOIN函數可以有多個參數,如果内部允許上下文傳遞的話,從一參,到二參,到三參等等,會導緻疊代的速度變得巨卡無比,甚至無法得出結果。
可以說從性能的角度考慮,微軟在設計CROSSJOIN函數的時候,就已經考慮到這個問題了,是以其不具備内部上下文傳遞的功能。
小夥伴們❤GET了麼?
白茶會不定期的分享一些函數卡片
(檔案在知識星球PowerBI丨需求圈)
這裡是白茶,一個PowerBI的初學者。