Spark中如何通过IN子句传入另一DataFrame的列值查询目标列
Spark DataFrame 实现方案
方案1:使用 left_semi 连接(生产环境推荐,适配任意数据量)
left_semi 是Spark专门为IN/EXISTS子查询场景设计的连接类型,只会返回左表(a_df)中与右表匹配成功的记录,不会产生数据冗余,性能最优,完全等价你给出的SQL逻辑。
import org.apache.spark.sql.functions.col // 你已实现的步骤:筛选B表符合条件的key val Bkey = b_df.filter(col("cond") === "D").select(col("key")) // 半连接匹配后取date去重 val result = a_df.join(Bkey, a_df("key") === Bkey("key"), "left_semi") .select("date") .distinct()
提示:使用连接前请确认a_df和b_df的key字段类型完全一致,避免隐式转换导致匹配失败。
方案2:小数据量场景使用 isin 方法
如果B表过滤后的key数据量很小(建议小于1万条),可以把key收集到Driver端后直接用isin方法,代码更简洁:
import org.apache.spark.sql.functions.col // 收集B表符合条件的key为数组 val BkeyArr = b_df.filter(col("cond") === "D").select(col("key")).as[String].collect() // 直接用isin过滤A表 val result = a_df.filter(col("key").isin(BkeyArr:_*)) .select("date") .distinct()
注意:该方案仅适合B过滤后key量级很小的场景,数据量过大时collect会拉取全量key到Driver端,容易引发Driver内存溢出,大数量场景必须使用方案1
内容的提问来源于stack exchange,提问作者Ma28
相关产品推荐
相关产品推荐

