Spark scala full join 在连接列上输出 null

Spark scala full join outputs null on joining column

我正在尝试合并 2 个具有相同列名的数据框以创建一个更大的新数据框,同时保留所有数据。如果存在相同的 ID,我会使用 coalesce 来替换一个数据框中的值。

连接和合并结果很好,但连接列 ("id") 在 id 存在时产生 null 值。不知道为什么:

示例:

val tmp = Seq(
  (1,"A"),
  (2,"B"),
  (3,"A"),
  (4,"A")
).toDF("id","label")


val tmp2 = Seq(
  (1,"B"),
  (2,"B"),
  (3,"B"),
  (5, "A")
).toDF("id","label")

代码:

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

// replace values in tmp(label) with tmp2(label) if both have same id.
val tmp3 = tmp.join(tmp2, tmp("id") === tmp2("id"), "fullouter")
           .select(tmp("id"), coalesce(tmp2("label"), tmp("label")))

output:
+----+----------------------+
|  id|coalesce(label, label)|
+----+----------------------+
|null|                     A|
|   1|                     B|
|   2|                     B|
|   3|                     B|
|   4|                     A|
+----+----------------------+

求职:

output:
+----+----------------------+
|  id|coalesce(label, label)|
+----+----------------------+
|   5|                     A|
|   1|                     B|
|   2|                     B|
|   3|                     B|
|   4|                     A|
+----+----------------------+

将联接更改为 "full" 我们的 "outer" 具有相同的结果。

您正在执行完全外部联接,因此它将合并两个表中的所有行。

由于您使用 tmp 中的 id 作为结果 ID,当 tmp2 中有一行 tmp 中不存在时,它不能接受一个有效的值,所以它是 null

要获得预期的输出,您可以在第一列中使用另一个 coalesce,与您在第二列中所做的相同

val tmp3 = tmp.join(tmp2, tmp("id") === tmp2("id"), "fullouter")
.select(coalesce(tmp("id"), tmp2("id")), coalesce(tmp2("label"), tmp("label")))
+----------------+----------------------+
|coalesce(id, id)|coalesce(label, label)|
+----------------+----------------------+
|               1|                     B|
|               3|                     B|
|               5|                     A|
|               4|                     A|
|               2|                     B|
+----------------+----------------------+