Power BI之DAX神功:第3卷第8回 INTERSECT與EXCEPT函數(shù)
《孫興華講PowerBI火力全開(kāi)》我們簡(jiǎn)單了介紹了一下INTERSECT與EXCEPT函數(shù),今天我們深入講原理。
一、INTERSECT函數(shù)

語(yǔ)法:INTERSECT(左表,右表) // 只支持兩張表
a. 返回兩張表共有的行,返回結(jié)果不去重。
b. 兩張表列的位置、列數(shù),數(shù)據(jù)類型三者都要相同
c. 保留左表數(shù)據(jù)沿襲
// 數(shù)據(jù)類型非常重要,詳見(jiàn)《DAX神功》第1卷第4回
【1】?jī)蓚€(gè)參數(shù)位置顛倒會(huì)影響數(shù)據(jù)沿襲
// 表1和表2 無(wú)連線關(guān)系

【新建表】交叉表1 = INTERSECT('表1','表2')

【新建表】交叉表2 = INTERSECT('表2','表1')

因?yàn)閰?shù)用的是整張表,所以它會(huì)考慮滿足條件的所有列。但是你觀察他始終返回的是左表所有列。換而言之,當(dāng)你對(duì)兩個(gè)參數(shù)交換位置時(shí),你要想清楚,你要的是誰(shuí)?可能你會(huì)說(shuō),兩張表字段都一樣時(shí),我拿誰(shuí)不一樣呀?還真不一樣。我們看一下下面兩個(gè)新建表
交叉表3 = addcolumns(INTERSECT('表2','表1'),"工資",CALCULATE(SUM('表2'[2月工資])))
// 因?yàn)閿?shù)據(jù)沿襲只保留INTERSECT函數(shù)左表的列

交叉表4 = addcolumns(INTERSECT('表2','表1'),"工資",CALCULATE(SUM('表1'[1月工資])))

學(xué)到這里的小伙伴應(yīng)該是懂?dāng)?shù)據(jù)沿襲的原理,我就不再重復(fù)講了。以上兩表您可以交換addcolumns第3參數(shù),再看看結(jié)果就理解,INTERSECT保留左表的數(shù)據(jù)沿襲。
【2】INTERSECT可以被TREATAS替代
交叉表5 = addcolumns(INTERSECT(VALUES('表2'[name]),VALUES('表1'[姓名])),"工資",CALCULATE(SUM('表2'[2月工資])))
// 保留左表的數(shù)據(jù)沿襲

交叉表6 = addcolumns(TREATAS(VALUES('表1'[姓名]), '表2'[name]),"工資",CALCULATE(SUM('表2'[2月工資])))
//?TREATAS第1參數(shù)篩選第2參數(shù),在第2參數(shù)上做標(biāo)記。注意TREATAS與INTERSECT參數(shù)位置問(wèn)題。

二、EXCEPT函數(shù)

語(yǔ)法:EXCEPT(左表,右表)? // 只支持兩張表
a.從左表中除去與右表重合的所有行,返回表不去重
b.兩張表列的位置、列數(shù),數(shù)據(jù)類型三者都要相同
c.保留左表數(shù)據(jù)沿襲
// 表1和表2無(wú)連線關(guān)系

【新建表】除去1 = EXCEPT('表1','表2')

【新建表】除去2 = EXCEPT('表2','表1')

【新建表】除去3 = EXCEPT(VALUES('表2'[name]),values('表1'[姓名]))

兩個(gè)參數(shù)位置顛倒會(huì)影響數(shù)據(jù)沿襲:原理與INTERSECT函數(shù)相同,都保留左表的數(shù)據(jù)沿襲,我不再重復(fù)舉例了
本節(jié)課在《The Definitive Guide to DAX》有兩個(gè)案例值得借鑒:我不能照搬人家案例,也不能照搬人家代碼,但是可以寫(xiě)出讀后感,供大家看書(shū)學(xué)習(xí)。
(1)例如查詢2020年購(gòu)買(mǎi)過(guò)產(chǎn)品但是2021年無(wú)購(gòu)買(mǎi)行為的客戶
可以用calculatetable或filter分別篩選2020和2021年的客戶表,通過(guò)EXCEPT(2020客戶表,2021客戶表) 這點(diǎn)很重要,因?yàn)槟阋獜?020年的表中除去2021年沒(méi)買(mǎi)過(guò)的,順序不要錯(cuò)。
(2)將上一年購(gòu)買(mǎi)過(guò)產(chǎn)品的客戶從當(dāng)前客戶集合中除去。
我們?cè)谥v時(shí)間智能日期函數(shù)時(shí)講過(guò)去年同期怎么算?
所有客戶 = DISTINCT(客戶列)? // 拿到所有客戶去重后的表,假設(shè)不止兩年,可以通過(guò)Filter或Calculate篩選 年>=20XX? 或? 日期>Date(20XX,12,31)
去年同期 = filter(所有客戶, 使用時(shí)間智能計(jì)算去年同期日期表) //使用Calculate也可以?,篩選去年同期滿足條件的客戶表
EXCEPT(所的客戶,去年同期)
三、回答網(wǎng)友問(wèn)題UNION、INTERSECT、EXCEPT僅篩選自身包含的列
UNION(合并)、INTERSECT(交叉)、EXCEPT(除去)都是返回一張表,但是這張表只能篩選自身包含的列,不能篩選其它列,即便保留了數(shù)據(jù)沿襲且表與表之間符合篩選關(guān)系也不可以篩選。PS:案例本身并無(wú)實(shí)際意義,只是為了講清楚篩選問(wèn)題


上面這個(gè)度量值,部分人理解有誤,并不是多端表篩選一端表,用多端表中的所有行篩選一個(gè)值。《DAX神功》第1卷第8回?已經(jīng)針對(duì)這個(gè)問(wèn)題做出了詳細(xì)解釋。
度量值=Calculate(計(jì)算器,篩選器)? ?
// 計(jì)算器返回一個(gè)值,篩選器篩選這個(gè)值。計(jì)算器是度量值的一部分,計(jì)算器不等于度量值

放到矩陣中的結(jié)果,與我們腦子里想的結(jié)果是一樣的:

從表面上看,通過(guò)UNION得到的這張表與多端表是一樣的:

但是,我們將這張表寫(xiě)到度量值中,會(huì)發(fā)現(xiàn)結(jié)果不同:

為什么會(huì)這樣?因?yàn)樵蹅冞€沒(méi)有講到擴(kuò)展表,所以我避開(kāi)這個(gè)知識(shí)來(lái)講


友情提示:下圖在手機(jī)上觀看,可以點(diǎn)擊后通過(guò)兩根手指放大。在電腦上觀看時(shí)可使用鼠標(biāo)滾輪放大。原理寫(xiě)在圖片上了。


孫興華講PowerBI火力全開(kāi)》PowerBI必學(xué)課程
https://www.bilibili.com/video/BV1qa4y1H7wp
《DAX神功》文字版合集:
https://www.bilibili.com/read/readlist/rl442274
《DAX神功》視頻版合集:
https://www.bilibili.com/video/BV1YE411E7p3
PowerBI(DAX函數(shù))、PowerQuery(M函數(shù))、Python辦公自動(dòng)化、Python爬蟲(chóng)、Python數(shù)據(jù)分析、ExcelVBA、WordVBA、AccessVBA、MySQL等等
https://www.bilibili.com/read/cv10222110