distinct去重多个字段_SparkSQL中map字段不能进行union、intersect、except操作吗?

通过SparkSQL,对两个存在map类型字段的Hive表进行union操作,报如下错误:

org.apache.spark.sql.AnalysisException: Cannot have map type columns in DataFrame which calls set operations(intersect, except, etc.), but the type of column map is map<string,string>;

1. 场景模拟

1)通过函数str_to_map/map生成map类型的字段,然后进行union操作

select 1 id, str_to_map("k1:v1,k2:v2") map

union

select 2 id, map("k1","v1","k2","v2") map

2)报错信息

org.apache.spark.sql.AnalysisException: Cannot have map type columns in DataFrame which calls set operations(intersect, except, etc.), but the type of column map is map<string,string>;;
Distinct
+- Union
   :- Project [1 AS id#116, str_to_map(k1:v1,k2:v2, ,, :) AS map#117]
   :  +- OneRowRelation
   +- Project [2 AS id#118, map(k1, v1, k2, v2) AS map#119]
      +- OneRowRelation

  at org.apache.spark.sql.catalyst.analysis.CheckAnalysis$class.failAnalysis(CheckAnalysis.scala:42)
  at org.apache.spark.sql.catalyst.analysis.Analyzer.failAnalysis(Analyzer.scala:95)
  at org.apache.spark.sql.catalyst.analysis.CheckAnalysis$$anonfun$checkAnalysis$1.apply(CheckAnalysis.scala:364)
  at org.apache.spark.sql.catalyst.analysis.CheckAnalysis$$anonfun$checkAnalysis$1.apply(CheckAnalysis.scala:85)
  at org.apache.spark.sql.catalyst.trees.TreeNode.foreachUp(TreeNode.scala:127)
  at org.apache.spark.sql.catalyst.analysis.CheckAnalysis$class.checkAnalysis(CheckAnalysis.scala:85)

2. 问题分析

根据报错信息,我们查看org.apache.spark.sql.catalyst.analysis.CheckAnalysis的checkAnalysis方法,第362行源码处理逻辑(错误信息是不是很熟悉呢?):

ee478898fd42eef89ee39f6fef58a8e7.png

关键看mapColumnInSetOperation中对逻辑计划的匹配:

eb335baa500317f0291dc2982babc5e4.png

针对逻辑计划中有Intersect、Except、Distinct的output"返回"的属性(Attribute)有map类型,或者Deduplicate的keys(也是Attribute)包含map字段类型,都会导致上述问题。

而union导致上述报错,是因为union会对结果去重,即distinct

3. 解决方案

询问后台小伙伴儿,目前的业务场景是考验不需要去重处理的。

那么我们都知道,union和union all的主要区别就是,前者会对结果去重,后者则不会。那么将union改为union all就好了。


关注 微信公众号:大数据学习与分享,获取更多技术干货

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值