Semi-join : filtrer par existence sans ramener de colonnes
left_semi filtre la table de gauche sur l'existence d'une clé à droite, sans dupliquer les lignes même si la droite contient des doublons.
Cas d'usage
Restreindre des événements aux utilisateurs d'une cohorte, sans risque de fan-out.
Prérequis
PySpark 3.x
Python
# Garder uniquement les événements des clients VIP vip_events = events.join(vip_customers, "customer_id", "left_semi") # Équivalent SQL : WHERE EXISTS (SELECT 1 FROM vip WHERE ...) # Piège évité : avec un inner join classique, si vip_customers contient # 3 lignes pour un même customer_id, chaque événement serait TRIPLÉ. # Le semi-join garantit : jamais plus de lignes qu'en entrée. assert vip_events.count() <= events.count()
Résultat
>>> events.count() 8421337 >>> events.join(vip_customers, "customer_id", "inner").count() 1248771 # fan-out : doublons côté référentiel >>> vip_events.count() 912448 # left_semi : jamais plus que l'entrée >>> vip_events.columns == events.columns True
PySparkSemi-joinFiltrageCohorte