如何在PySpark中关联左右表,保留右表所有行并匹配左表字段?
解决PySpark DataFrame关联匹配需求
看你的数据和需求,核心是让右表的每条记录匹配左表中对应session_id的time值,最终保留右表的完整记录结构并补上对应时间。
问题原因
你用left join得到不符合预期的记录,是因为left join会强制保留左表的所有行——左表中session_id=3的记录在右表没有匹配项,所以结果里会多出一条res_id=null, sess_id=null, time=30的冗余记录,这和你的需求不符。
正确实现方式
你需要用inner join或者right join,结合正确的关联字段(右表sess_id ↔ 左表session_id),具体代码如下:
1. 创建示例DataFrame
from pyspark.sql import SparkSession spark = SparkSession.builder.appName("MatchSessionTime").getOrCreate() # 左表:session_id与对应时间 left_data = [(1, 10), (2, 20), (3, 30)] left_df = spark.createDataFrame(left_data, ["session_id", "time"]) # 右表:res_id与关联的sess_id right_data = [(1, 1), (2, 2), (1, 1)] right_df = spark.createDataFrame(right_data, ["res_id", "sess_id"])
2. 执行关联并筛选目标字段
# 方式1:inner join(仅保留两边匹配的记录,完全符合你的当前场景) result_df = right_df.join( left_df, right_df.sess_id == left_df.session_id, "inner" ).select("res_id", "sess_id", "time") # 方式2:right join(如果右表存在sess_id不在左表的情况,会保留右表记录并将time设为null,更通用) # result_df = left_df.join( # right_df, # left_df.session_id == right_df.sess_id, # "right" # ).select("res_id", "sess_id", "time") # 查看最终结果 result_df.show()
3. 输出结果
运行后会得到你想要的结构:
+------+-------+----+ |res_id|sess_id|time| +------+-------+----+ | 1| 1| 10| | 1| 1| 10| | 2| 2| 20| +------+-------+----+
关键注意点
- 关联字段必须准确匹配:右表的
sess_id对应左表的session_id,不能写错字段名。 - 按需选择join类型:
- inner join:适合当前场景(右表所有sess_id都能在左表找到匹配),只保留两边都匹配的记录。
- right join:适合可能存在不匹配的通用场景,会完整保留右表的所有记录。
内容的提问来源于stack exchange,提问作者user2913139
相关产品推荐
相关产品推荐

