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

如何合并多同结构表?缺失Key取用前表对应值

问题描述

现有多张结构相同的数据表,示例如下:

table1:

==========
 |id |  a |
 ==========
 |1  | aa |
 |2  | bb |
 |3  | cc |
 |4  | dd |
 ==========

table2:

==========
 |id |  a |
 ==========
 |1  | aa |
 |2  | bb |
 |3  | cc |
 |4  | dd |
 ==========

table3:

===========
 |id |  a  |
 ==========
 |1  | aaa |
 |2  | bbb |
 |3  | ccc |
 ===========

需要合并这3张表生成包含所有id的结果表,规则为:

  • 优先取table3的对应内容;
  • 若table3缺失某id,取table2的对应值;
  • 若table2也缺失(假设存在该场景),再取table1的值。

目标输出:

============
 |id |  a   |
 ============
 |1  |  aaa |
 |2  |  bbb |
 |3  |  ccc |
 |4  |  dd  |
 ============

当前尝试代码:

finaloutput = \
    table3 \
        .join(table2, (table3.id == table2.id), "full") \
        .join(table1, (table3.id == table1.id), "full") 
解决方案

方法1:Full Join + Coalesce 函数

你的思路方向正确,但直接多次full join会生成重复的字段(如id、id_1、id_2和a、a_1、a_2),需要用coalesce函数按优先级取值,同时统一id字段:

from pyspark.sql.functions import coalesce, col

# 按id做三次full join
joined = table3.join(table2, on="id", how="full") \
               .join(table1, on="id", how="full")

# 按优先级取a的值,id取非空值
finaloutput = joined.select(
    coalesce(col("id"), col("id"), col("id")).alias("id"),
    coalesce(col("a"), col("a"), col("a")).alias("a")
)

coalesce会返回第一个非空值,正好匹配table3 > table2 > table1的优先级要求;id字段通过coalesce取非空值,确保所有id都被保留。

方法2:Union All + 窗口函数(扩展性更强)

如果后续需要新增更多表,多次join会非常繁琐,用union all合并所有表后,通过窗口函数按优先级筛选:

from pyspark.sql.window import Window
from pyspark.sql.functions import row_number, col, lit

# 给每个表标记优先级:table3最高(1),table2次之(2),table1最低(3)
table3_with_prio = table3.withColumn("priority", lit(1))
table2_with_prio = table2.withColumn("priority", lit(2))
table1_with_prio = table1.withColumn("priority", lit(3))

# 合并所有表数据
union_df = table3_with_prio.unionAll(table2_with_prio).unionAll(table1_with_prio)

# 按id分组,取优先级最高的记录
window_spec = Window.partitionBy("id").orderBy("priority")
finaloutput = union_df.withColumn("row_num", row_number().over(window_spec)) \
                      .filter(col("row_num") == 1) \
                      .drop("priority", "row_num")

这种方法新增表时只需添加一条带优先级的union语句,扩展性更好。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 13:20:28