篩選資料用的 SQL Join : Left Semi, Left Anti

不管是查詢資料庫或是處理資料的 Dataframe 等,相信大家對於使用 SQL 語法 Join 不同資料表的情境都不會太陌生,而最常見的就是使用 Inner Join 與 Outer Join。

但之前也有遇到「不需要拿另一張表的資料,但要用它來過濾特定資料」的情況,這時候就可以考慮使用 Left Semi/Anti Join。


Left Semi Join

如果使用 A Left Semi Join B,其意義為「從 A 取出也有在 B 之中的資料」。

假設有兩個資料表分別為顧客資料訂單資訊,今天的情境是希望「寄送電子信給三十天內有消費的會員」,實際上需要用的欄位可能只有會員名稱Email 地址,而完全不需要訂單資訊。因此 SQL 查詢可能就像是

SELECT name, email
FROM members
LEFT SEMI JOIN orders
ON members.user_id = orders.user_id
WHERE ... //三十天內有購買

如此一來就可以只拿到顧客資料表中所需要的資料。


Left Anti Join

使用 A Left Anti Join B,則是相反的意義「從 A 取出不在 B 之中的資料」。

若情境為「寄送折價券給超過一年未消費的使用者」,同樣不需要拿取訂單相關的資訊但要用來過濾。

SELECT name, email
FROM members
LEFT ANTI JOIN orders
ON members.user_id = orders.user_id
WHERE ... //一年內未購買

總結

這是兩個比較少看到大家拿出來討論的 Join 方法,我認為優點在於可以避免寫出 ... WHERE user_id IN (SELECT user_id FROM B WHERE ...) 或是 SELECT A.name, A.email FROM A LEFT JOIN B ON ... 這類的語句,我想應該對可讀性有幫助。