You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Scala中获取DataFrame 1中存在但DataFrame 2中不存在的数据

在Scala中筛选DF1独有的数据(DF1存在但DF2不存在的记录)

你好呀!针对你要找出DF1里有但DF2里没有的数据这个需求,在Spark Scala里有几种实用的方法,我给你拆解一下:

方法1:用except算子(整行对比+自动去重)

如果你的DF1和DF2结构完全一致(列名、类型都匹配),想要找出整行在DF2中不存在的记录,except是最直接的选择,不过它会自动去重哦:

// 直接得到DF1独有的行(去重后)
val df1UniqueRows = df1.except(df2)
df1UniqueRows.show()

举个例子:如果DF1里有5条一模一样的行,而DF2里没有,用except返回的结果只会保留1条。

方法2:用左外连接+过滤(保留重复行,自定义关联键)

如果需要保留DF1的重复行,或者只需要根据某几个关键字段判断“是否存在”(比如你的例子里的PRS_ID),可以用左外连接后过滤null值:

// 以PRS_ID为关联键做左连接,保留DF1所有行
val leftJoinResult = df1.join(df2, Seq("PRS_ID"), "left_outer")
// 过滤出DF2中没有匹配到的行(DF2的PRS_ID为null说明无匹配)
val df1Only = leftJoinResult.filter(df2("PRS_ID").isNull)
// 只保留DF1的原始列(可选,根据需求调整)
val finalResult = df1Only.select(df1.columns.map(df1(_)): _*)
finalResult.show()

这种方法的灵活性很高,你可以根据实际业务选择关联的字段,比如同时用REQ_ID和PRS_ID作为关联键,只需要把Seq("PRS_ID")改成Seq("REQ_ID", "PRS_ID")就行。

方法3:用anti join(Spark 2.1+,语义明确且高效)

这是我最推荐的方法,Spark从2.1版本开始支持anti join,专门用来解决“左表有但右表没有”的问题,不仅语义清晰,还会保留DF1的重复行,而且结果里只有DF1的列:

// 基于PRS_ID做anti join,直接得到DF1中在DF2无匹配的行
val df1Only = df1.join(df2, Seq("PRS_ID"), "anti")
df1Only.show()

这个方法不需要额外处理过滤或列选择,完全贴合你的需求,效率也比左连接过滤更高。

额外提示

如果DF2里的PRS_ID是DF1中REQ_ID的前缀(比如你例子里的情况),可以先对DF1的REQ_ID做字符串截取,再和DF2的PRS_ID关联,比如:

import org.apache.spark.sql.functions.substring
val df1WithShortReqId = df1.withColumn("SHORT_REQ_ID", substring($"REQ_ID", 1, 18))
val df1Only = df1WithShortReqId.join(df2, $"SHORT_REQ_ID" === df2("PRS_ID"), "anti")

内容的提问来源于stack exchange,提问作者Krishna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:23:17