如何合并多同结构表?缺失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
相关产品推荐
相关产品推荐

