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

Apache Spark关联键含空值时如何正确Join获取两边全量字段数据

根因说明

Spark 默认的等值匹配逻辑中,null 和 null 的判定结果为不相等,因此你用包含空值的字段作为关联键时,两边相同的空键不会被识别为匹配项,才会出现左连接取不到name、右连接取不到id、全连接拆分为4条记录的问题。

解决方案

有两种常用实现方式,均可满足空值关联匹配的需求:

方案1:使用空安全相等运算符写关联条件

Spark 提供的 <=> 是空安全相等运算符,当两边值相等或两边均为null时会返回true,刚好匹配你的需求,代码如下:

import org.apache.spark.sql.functions.col

// 先重命名df1的id字段
val df1WithRename = df1.withColumnRenamed("id", "tally_summary_id")

// 手动定义关联条件,所有键都用空安全相等
val joinCondition = 
  df1WithRename("tally_number") <=> df2("tally_number") &&
  df1WithRename("work_order_number") <=> df2("work_order_number") &&
  df1WithRename("work_order_item_number") <=> df2("work_order_item_number") &&
  df1WithRename("company_code") <=> df2("company_code")

// 左连接即可,不需要全连接
val finalDf = df1WithRename.join(df2, joinCondition, "left")
  // 选取需要的输出字段,避免重复列
  .select(
    df1WithRename("tally_number"),
    df1WithRename("work_order_number"),
    df1WithRename("work_order_item_number"),
    df1WithRename("company_code"),
    col("tally_summary_id"),
    col("name")
  )

方案2:空值填充后再关联

如果你的业务场景中这两个字段的空值没有特殊含义,可以先把两边关联键的空值统一填充为同一个占位值(比如空字符串),再用常规的等值关联即可:

// 需要填充空值的关联键列表
val fillColumns = Seq("work_order_number", "work_order_item_number")
val fillValue = ""

// 两边分别处理空值,同时重命名df1的id
val df1Processed = df1
  .withColumnRenamed("id", "tally_summary_id")
  .na.fill(fillValue, fillColumns)
val df2Processed = df2.na.fill(fillValue, fillColumns)

// 常规等值关联即可
val finalDf = df1Processed.join(
  df2Processed,
  Seq("tally_number", "work_order_number", "work_order_item_number", "company_code"),
  "left"
)

两种方案执行后的输出结果均和你期望的一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 06:48:03