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

如何在Inner Join后保留DataFrame df1的原有格式?

Spark DataFrame内连接后保留原表列的解决方案

问题场景

我有两个DataFrame:

  • df1包含列:first_name、last_name、id、location、phone_number(实际有近30列)
  • df2包含列:last_name、id、location、employer

需求是通过last_name和id做内连接,只保留两表中这两个字段都匹配的行,并且只保留df1的原有列,不要引入df2的额外列,也避免出现列名歧义。

当前用这段代码执行连接:

df1.join(df2, df1.col("last_name").equalTo(df2.col("last_name").and(df1.col("id").equalTo(df2.col("id"))), "inner");

结果不仅多出了df2的列(比如employer),id、last_name还出现了重复歧义的列。


解决办法

办法1:用关联键筛选替代完整连接(最省事)

不用做全表join,直接筛选df1中(last_name, id)存在于df2的行,直接得到df1的原格式:

// 先提取df2的连接键
val df2Keys = df2.select("last_name", "id")
// 用inner join关联键,自动合并重复的连接列,直接得到df1的所有列
val result = df1.join(df2Keys, Seq("last_name", "id"), "inner")

或者用exists子查询的写法:

import org.apache.spark.sql.functions._

val result = df1.filter(
  exists(df2, 
    row => row.getAs[String]("last_name") === col("last_name") && row.getAs[String]("id") === col("id")
  )
)

办法2:join后直接选取df1的全部列

如果一定要用原join逻辑,join完成后直接通过df1的列名集合选取所有列,不用逐个手写:

// 用Seq指定连接键,避免歧义列
val joinedDf = df1.join(df2, Seq("last_name", "id"), "inner")
// 直接选取df1的所有列
val result = joinedDf.select(df1.columns.map(col): _*)

办法3:表别名+精准选取原表列

如果连接条件需要更复杂的列判断,可以给表加别名,之后直接选取别名表的所有列:

val a = df1.alias("a")
val b = df2.alias("b")

val result = a.join(
  b,
  a("last_name") === b("last_name") && a("id") === b("id"),
  "inner"
).select(a.columns.map(a(_)): _*)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 09:40:45