【Spark SQL】两个DataFrame full join之后字段选择问题解决

最近工作上用到Spark SQL来处理数据。但是期间遇到两个表full join的问题,网上比较少关于spark SQL full join的资料,后面Google了一番找到了问题的核心。在这边做一个记录,方便他人也方便自己复盘。

工作的数据涉及保密,这边用两个dataframe来代替。

1. 先创建dataframe:

val left = Seq((0, "zero"), (1, "one")).toDF("id", "left")
val right = Seq((0, "zero"), (2, "two"), (3, "three")).toDF("id", "right")

2. 对两个dataframe进行full join:

scala> left.join(right, Seq("id"), "fullouter").show
+---+----+-----+
| id|left|right|
+---+----+-----+
|  1| one| null|
|  3|null|three|
|  2|null|  two|
|  0|zero| zero|
+---+----+-----+

 注:这里Seq是join方法的一个参数,里面放表要join的公共的key。

3. 对这句sql进行explain:

scala> left.join(right, Seq("id"), "fullouter").explain
== Physical Plan ==
*Project [coalesce(id#50, id#60) AS id#85, left#51, right#61]
+- SortMergeJoin [id#50], [id#60], FullOuter
   :- *Sort [id#50 ASC NULLS FIRST], false, 0
   :  +- Exchange hashpartitioning(id#50, 200)
   :     +- LocalTableScan [id#50, left#51]
   +- *Sort [id#60 ASC NULLS FIRST], false, 0
      +- Exchange hashpartitioning(id#60, 200)
         +- LocalTableScan [id#60, right#61]

从上面可以看出,*Project [coalesce(id#50, id#60) AS id#85, left#51, right#61]中已经对公共的key--“id”进行了coalesce判断,所以在涉及表字段选择的时候,就不需要判断哪个字段是否为null了。

举例:

dataframe1: id, name, age
dataframe2: id, name, value

val result = dataframe1.as("d1").join(dataframe2.as("d2"), Seq("id","name"), "full")
    .selectExpr("id","name","d1.age","d2.value")

 这边的公共key,id和name,就不能再加别名了,或者写成下面这样都是不对的,这和hive的sql不一样了。

这么写是会报错的:
val result = dataframe1.as("d1").join(dataframe2.as("d2"), Seq("id","name"), "full")
    .selectExpr("coalesce(d1.id,d2.id)","coalesce(di.name,d2.name)","d1.age","d2.value")

 

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值