在Spark联接[Scala]中包含空值

在Spark联接[Scala]中包含空值,scala,apache-spark,apache-spark-sql,Scala,Apache Spark,Apache Spark Sql,我有2个dfs,我想对所有列进行内部联接 val seq1 = Seq((Some("1"), Some("Cat")), (Some("2"), Some("Dog")), (Some("3"), None)) val df1 = seq1.toDF("id", "name") val s2 = Seq((Some("1"), Some("Cat")), (Some("2"), Some("Dog")), (Some("3"), None)) val df2 = s2.toDF("id",

我有2个dfs,我想对所有列进行内部联接

val seq1 = Seq((Some("1"), Some("Cat")), (Some("2"), Some("Dog")), (Some("3"), None))
val df1 = seq1.toDF("id", "name")

val s2 = Seq((Some("1"), Some("Cat")), (Some("2"), Some("Dog")), (Some("3"), None))
val df2 = s2.toDF("id", "name")

val s3 = Seq((Some("1"), Some("Cat")), (Some("2"), Some("Dog")), (Some("3"), None))
val df3 = s3.toDF("id", "name")
我希望
df1.join(df2,df1.columns,“inner”)
生成df3,但现在它排除了
(“3”,null)

我使用
.eqNullSafe
看到了一些答案,但我不确定如何将其应用于scala代码。我想要一个通用的解决方案,可以适用于任何dfs-不知道预先列的名称


我是否可以执行类似于
df1.join(df2,df1.columns.map(c=>col(c).eqNullSafe()):*,“inner”)
?编译器不喜欢它,但这正是它的想法。

您可以像这样构建自定义连接条件:

val joinCondition = df1.columns.foldLeft(lit(true))((acc,c) => acc and  (df1(c) === df2(c) or df1(c).isNull or df2(c).isNull))

df1.join(df2, joinCondition, "inner")
  .select(df1("*"))

但是由于您的
df2
在您的测试用例中是空的,这仍然会导致一个空结果。您不能使用
union
或简单地使用
left join

因此当前
f1.join(df2,df1.columns,“inner”)
提供一个空数据帧。
df1.join(df2,df1.columns,“left”)
df1.union(df2)
有什么问题?你能添加一个更完整的测试用例吗?我错了!更新
。选择(df1(“*”)
是一个很棒的技巧!我在df2中重命名了COL,这样我就可以删除它们,而不会在以后发生命名冲突。非常感谢。