热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

HiveSQL一天一个小技巧:如何借助于str_to_map进行行转列

目录0需求描述1需求分析2小结0需求描述有如下表格partnerlabelvalue001原始证件号9111030275820228X7001统一社会信用代码911103

目录

0 需求描述

1 需求分析

2 小 结



0 需求描述

有如下表格

partnerlabelvalue
001原始证件号9111030275820228X7
001统一社会信用代码9111030275820228X7
002原始证件号6111030255820228Y7
002统一社会信用代码6111030255820228Y7

需要转换如下结果:

partner原始证件号统一社会信用代码
0019111030275820228X78111030275820228X7
0026111030255820228Y75111030255820228Y7


1 需求分析

(1)创建数据

create table t as
select '001' as partner , '原始证件号' as label,'9111030275820228X7' as value
union all
select '001' as partner , '统一社会信用代码' as label,'8111030275820228X7' as value
union all
select '002' as partner , '原始证件号' as label,'6111030255820228Y7' as value
union all
select '002' as partner , '统一社会信用代码' as label,'5111030255820228Y7' as value

(2) 数据分析

方法1:借助于聚合函数max()与case when实现。代码如下

select partner,max(case when label='原始证件号' then value else null end) as a,max(case when label='统一社会信用代码' then value else null end) as b
from t
group by partner

 利用max()函数可以有效的去除NULL值,max()函数在计算的时候会忽略NULL值

方法2:借助于str_to_map实现

str_to_map(字符串参数, 分隔符1, 分隔符2)

使用两个分隔符将文本拆分为键值对。

分隔符1将文本分成K-V对,分隔符2分割每个K-V对。对于分隔符1默认分隔符是 ',',对于分隔符2默认分隔符是 '='

测试如下:

select str_to_map('aaa:11&bbb:22', '&', ':')+--------------------------+
| _c0 |
+--------------------------+
| {"bbb":"22","aaa":"11"} |
+--------------------------+
2 rows selected (2.226 seconds)

结果返回一个json对象。其中第一个参数用来分割整个串,指名需要按照哪个符号来分割K-V对,第二个参数用来指明K-V对中的分隔符。

从这测试案例也可以看出如果需要将数据拼接成一个json数组,也可以使用str_to_map的形式。

针对本问题:我们先做如下变换

第一步:先将label 和value拼接成K-V对

select concat_ws(':',label,value)from t +------------------------------+
| _c0 |
+------------------------------+
| 统一社会信用代码:8111030275820228X7 |
| 原始证件号:9111030275820228X7 |
| 原始证件号:6111030255820228Y7 |
| 统一社会信用代码:5111030255820228Y7 |
+------------------------------+

第二步: 利用collect_list()函数将多行转成单列

select concat_ws(',',collect_list(concat_ws(':',label,value))) from t group by partner+----------------------------------------------------+
| _c0 |
+----------------------------------------------------+
| 原始证件号:6111030255820228Y7,统一社会信用代码:5111030255820228Y7 |
| 统一社会信用代码:8111030275820228X7,原始证件号:9111030275820228X7 |
+----------------------------------------------------+

第三步:利用str_to_map()函数组合成json形式

select str_to_map(concat_ws(',',collect_list(concat_ws(':',label,value))),',',':' )from t group by partner+----------------------------------------------------+
| _c0 |
+----------------------------------------------------+
| {"原始证件号":"6111030255820228Y7","统一社会信用代码":"5111030255820228Y7"} |
| {"统一社会信用代码":"8111030275820228X7","原始证件号":"9111030275820228X7"} |
+----------------------------------------------------+

第四步:map结构的取数方式进行行转列。具体SQL如下

select partner,mmap['原始证件号'] as a ,mmap['统一社会信用代码'] as b from (select partner,str_to_map(concat_ws(',',collect_list(concat_ws(':',label,value))),',',':' ) as mmapfrom t group by partner) t

+----------+---------------------+---------------------+
| partner | a | b |
+----------+---------------------+---------------------+
| 002 | 6111030255820228Y7 | 5111030255820228Y7 |
| 001 | 9111030275820228X7 | 8111030275820228X7 |
+----------+---------------------+---------------------+2 rows selected (1.178 seconds)

方法1和方法2对比来看,方法2采用str_to_map的方法更优雅,效率更高一点,这是因为hive底层在这种高级的数据结构上做了优化,逻辑更优一点。

2 小 结

本文分析了一种采用str_to_map的方法进行行转列的方法,该方法结构优雅,从执行效率上来看性能更优,比通用的聚合函数加case when的方法效率更高。通过本文也可以利用str_to_map来拼接json串,不失为一种很好的技巧。


推荐阅读
  • ubuntu用sqoop将数据从hive导入mysql时,命令: ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • web.py开发web 第八章 Formalchemy 服务端验证方法
    本文介绍了在web.py开发中使用Formalchemy进行服务端表单数据验证的方法。以User表单为例,详细说明了对各字段的验证要求,包括必填、长度限制、唯一性等。同时介绍了如何自定义验证方法来实现验证唯一性和两个密码是否相等的功能。该文提供了相关代码示例。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 网址:https:vue.docschina.orgv2guideforms.html表单input绑定基础用法可以通过使用v-model指令,在 ... [详细]
author-avatar
icrochildren1035_175
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有