【hive】列转行—collect_set()/collect_list()/concat_ws()函数的使用场景

文章目录

  • 一、collect_set()/collect_list()
  • 二、实际运用
    • 把同一分组的不同行的数据聚合成一个行
    • 用下标可以随机取某一个
    • 聚合后的中的值用‘|’分隔开
    • 使用collect_set()/collect_list()使得全局有序


一、collect_set()/collect_list()

在 Hive 中想实现按某字段分组,对另外字段进行合并,可通过collect_list()或者collect_set()实现。

  • collect_set()函数与collect_list()函数:列转行专用函数,都是将分组中的某列转为一个数组返回。有时为了字段拼接效果,多和concat_ws()函数连用。

  • collect_set()与collect_list()的区别:

    • collect_list()函数 - - 不去重
    • collect_set()函数 - - 去重

有点类似于Python中的列表与集合。


二、实际运用

创建测试表及插入数据

drop table test_1;
create table test_1(
id string,
cur_day string,
rule string
) 
row format delimited fields terminated by ',';insert into test_1 values
('a','20230809','501'),('a','20230811','502'),('a','20230812','503'),('a','20230812','501'),('a','20230813','512'),('b','20230809','511'),('b','20230811','512'),('b','20230812','513'),('b','20230812','511'),('b','20230813','512'),('b','20230809','511'),('c','20230811','512'),('c','20230812','513'),('c','20230812','511'),('c','20230813','512');

把同一分组的不同行的数据聚合成一个行

举例1:按照id,cur_day分组,取出每个id对应的所有rule(不去重)。

select id,cur_day,collect_set(rule) as rule_total  from test_1 group by id,cur_day order by id,cur_day;

在这里插入图片描述
举例2:按照id,cur_day分组,取出每个id对应的所有rule(去重)。

select id,cur_day,collect_list(rule) as rule_total from test_1 group by id,cur_day order by id,cur_day;

在这里插入图片描述

用下标可以随机取某一个

select id,cur_day,collect_list(rule)[0] as rule_one from test_1 group by id,cur_day order by id,cur_day;select id,cur_day,collect_set(rule)[0] as rule_one from test_1 group by id,cur_day order by id,cur_day;

在这里插入图片描述

聚合后的中的值用‘|’分隔开

select id,cur_day,concat_ws('|',collect_list(rule)) as rule_total from test_1 group by id,cur_day order by id,cur_day;select id,cur_day,concat_ws('|',collect_set(rule)) as rule_totalfrom test_1 group by id,cur_day order by id,cur_day;

在这里插入图片描述

使用collect_set()/collect_list()使得全局有序

现在需求:严格按照同一个id进行分组,规则按时间升序排序,使用collect_list()将时间与规则按升序排序且一 一 对应展示出来。

1.原数据详情:

在这里插入图片描述
2.要求输出结果如下:按id分组,将rule按cur_day升序排序,将cur_day,rule放在一个列表中,并且列表中cur_day与rule是按升序一一对应的关系。
在这里插入图片描述

3.实现思路:将其使用row_number()over(partition by id order by cur_day as)排序,然后再使用collect_list()或者collect_list()/collect_set()进行聚合就可以了。

drop table test_2 ;
create table test_2 as 
select id,collect_list(cur_day),collect_list(rule) 
from (
select t.id,t.cur_day,t.rule,row_number() over(partition by id order by cur_day asc) rn from test_1 t
)t group by id ;select * from test_2 group by id order by id;

在这里插入图片描述

4.发现问题:cur_day数组内的时间并没有按照升序排序输出。

5.原因分析:

  • HiveQL执行时,大部分情况都会转换为MR来执行,当开户多个Mapper的时候,Mapper1可能处理的是id为a,cur_day排名为1、2、3的数据,Mapper2可能处理的id为a,cur_day排名为4、5、6的数据。
  • collect_list()的底层是ArrayList来实现的,当put到ArrayList的时候,不一定是哪个Mapper先,哪个Mapper后,所以会出现20230811、20230812、20230813在20230809前面的情况。所以,row_number() over(partitiion by order by) 与collect_list一起使用只能实现局部有序,不能实现全局有序。

6.解决方案:

  • 方法一:全局 order by
drop table test_2 ;
create table test_2 as 
select id,collect_list(cur_day),collect_list(rule) 
from (select t.* from(select t.id,t.cur_day,t.rule,row_number() over(partition by id order by cur_day asc) rn from test_1 t) t order by rn 
)t group by id ;select * from test_2 group by id order by id;

在这里插入图片描述

  • 方法二:distribute by + order by
select
id,collect_list(cur_day),collect_list(rule) 
from(selectt.id,t.cur_day,t.rule,row_number()over(partition by id order by cur_day asc) as rnfrom(selectt.id,t.cur_day,t.rulefrom test_1 tdistribute by id sort by cur_day asc)t
)t 
group by id order by id;

在这里插入图片描述

  • 方法三:sort_array (只支持升序)
select
id,concat_ws(',',collect_list(cur_day)),regexp_replace(concat_ws(',',sort_array(collect_list(concat_ws('|' ,lpad(cast(rn as string),2,'0') ,rule)))),'\\d+\\|','') 
from(
select t.* 
from(
select
id,cur_day,rule,
row_number()over(partition by id order by cur_day asc) as rn
from test_1
)t order by rn
)t group by id order by id;

在这里插入图片描述

上面代码用到相关函数解析:

  • lpad(str,len,pad) 函数:这个是对排序值(也就是rule)来补位的,当要排序的值过大时,因为sort_array是按顺序对字符进行排序(即11会在2的前面),所以可以使用此函数补位(即将1,2,3,4变成01,02,03,04),这样就能正常排序了。

    • 第一个参数:你要补齐的字段值
    • 第二个参数:补齐之后总共的位数
    • 第三个参数:你要在左边填充的字符
  • regexp_replace(strA,strB,strC) 函数:将字符串A中的符合JAVA正则表达式B的部分替换为C,即排序之前将序号使用,跟需要的字段拼接,而排序之后,需要将序号和:去掉

  • sort_array(expr[, ascendingOrder])默认是升序排序,但其中可以带参数,默认为True,即按升序,如果输入False,就会按降序排序。

    • expr:一个可排序元素的 ARRAY 表达式。
    • ascendingOrder:可选的 BOOLEAN 表达式,默认值为 True,即按升序。
select id
,concat_ws(',',sort_array(collect_list(concat_ws('|' ,lpad(cast(rn as string),2,'0') ,rule)))) as middle_value --中间值
,regexp_replace(concat_ws(',',sort_array(collect_list(concat_ws('|' ,lpad(cast(rn as string),2,'0') ,rule)))),'\\d+\\|','')  as result_values --最终结果
from(
select t.* 
from(
select
id,cur_day,rule,
row_number()over(partition by id order by cur_day asc) as rn
from test_1
)t order by rn
)t group by id order by id;

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/77618.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通过数据模板自动生成表格table

1.数据模板中的主要几个参数需要注意下(需要加样式可自由设置参数): title:填入表格的内容 col:1,占一列,row: 3,占3行 align:center居中对齐, pdL:14,padding-left:14, bold:true,加粗 width:100&#xff…

简单聊聊G1垃圾回收算法整个流程 --- 理论篇 -- 下

简单聊聊G1垃圾回收算法整个流程 --- 理论篇 -- 下 软实时性预测转移时间预测可信度GC 暂停处理的调度并发标记中的暂停处理 分代 G1 GC 模式不同点新生代区域分代对象转移具体转移流程分代选择回收集合设置最大新生代区域数 GC的切换GC执行的时机 总结 上一篇 文章我们简单看了…

【C++】常用排序算法

0.前言 1.sort #include <iostream> using namespace std;// 常用排序算法 sort #include<vector> #include<algorithm>//利用仿函数 打印输出 class myPrint { public:void operator()(int val){cout << val << " ";} };//利用普通函…

【C++深入浅出】类和对象中篇(六种默认成员函数、运算符重载)

目录 一. 前言 二. 默认成员函数 三. 构造函数 3.1 概念 3.2 特性 四. 析构函数 4.1 概念 4.2 特性 五. 拷贝构造函数 5.1 概念 5.2 特性 六. 运算符重载 6.1 引入 6.2 概念 6.3 注意事项 6.4 重载示例 6.5 赋值运算符重载 6.6 前置和后置运算符重载 七. c…

Excel显示列号

默认表格打开列以字母显示 设置方法 文件 -> 工具 -> 选项 -> 常规与保存 设置后效果如下图

使用高斯混合模型进行聚类

一、说明 高斯混合模型 &#xff08;GMM&#xff09; 是一种基于概率密度估计的聚类分析技术。它假设数据点是由具有不同均值和方差的多个高斯分布的混合生成的。它可以在某些结果中提供有效的聚类结果。 二、Kmean算法有效性 K 均值聚类算法在每个聚类的中心周围放置一个圆形边…

推荐10个AI人工智能技术网站(一键收藏,应有尽有)

1、Mental AI MentalAI&#xff08;https://ai.ciyundata.com/&#xff09;是一种基于文心大模型的知识增强大语言模型&#xff0c;专注于自然语言处理&#xff08;NLP&#xff09;领域的技术研发。它具备强大的语义理解和生成能力&#xff0c;能够处理各种复杂的自然语言任务。…

Python第一次作业练习

题目分析&#xff1a; """ 参考学校的相关规定。 对于四分制&#xff0c;百分制中的90分及以上可视为绩点中的4分&#xff0c;80 分及以上为3分&#xff0c;70 分以上为2分&#xff0c;60 分以上为1分; 五分制中的5分为四分制中的4分&#xff0c;4分为3分&#…

RNA 37. SCI 文章中基于转录组计算肿瘤免疫浸润得分

这期推荐软件包 xCell:数字化描绘组织细胞异质性景观&#xff0c;通过它可以计算bulk 转录组的免疫浸润得分&#xff0c;下面我们就看看怎么来实现吧&#xff01; 简 介 组织是由许多细胞类型组成的复杂环境。在癌症领域&#xff0c;了解肿瘤微环境中的细胞异质性是一个新兴…

【css | loading】好看的loading特效

示例&#xff1a; https://code.juejin.cn/pen/7277764394618978365 html <div class"pl"><div class"pl__dot"></div><div class"pl__dot"></div><div class"pl__dot"></div><div c…

第51节:cesium 范围查询(含源码+视频)

结果示例: 完整源码: <template><div class="viewer"><el-button-group class="top_item"><el-button type=

Axure RP 10汉化版下载 Axure RP 10 mac授权码

Axure RP10汉化版是最强大的计划&#xff0c;原型设计和交付给开发人员的方法&#xff0c;而无需编写代码。能够制作逼真的&#xff0c;动态形式的原型。 Axure RP 10汉化版下载 Axure RP 10 mac授权码 RP 10有什么新功能&#xff1f; 1.显示动态面板 使用Axure RP 10&…

docker 镜像内执行命令显示:You requested GPUs: [0] But your machine only has: []

目录 问题描述&#xff1a; 问题解决&#xff1a; 问题描述&#xff1a; 在docker 镜像环境中&#xff0c;执行“docker exec -it container_name /bin/bash “进入容器之后&#xff0c;执行对应的python命令&#xff0c;显示You requested GPUs: [0] But your machine only…

【深度学习】P1 单层神经网络 - 线性回归(待完成)

单层神经网络 - 线性回归 线性回归基本要素1. 模型2. 模型训练3. 训练数据4. 损失函数5. 优化算法6. 模型预测 线性回归与神经网络1. 神经网络图 以一个简单的房屋价格预测为例&#xff0c;介绍解释线性回归这一单层神经网络。无需纠结于什么是单层神经网络&#xff0c;在本文的…

Hadoop_02

hadoop相比于传统文件系统的优点&#xff1a; 1.无限扩展 2.传统文件元数据分布在不同的机器上难以寻找&#xff0c;通过将元数据统一存放在一个服务器上解决 3.传统文件太大导致上传下载慢&#xff0c;通过分块并行上传到服务器解决 4.副本机制数据不容易丢失&#xff0c;解决…

JavaScript里面的二进制

概述 最近在做IOT设备配网开发的时候&#xff0c;处理了很多跟二进制、字节相关的事情&#xff0c;总结了一下JavaScript中有关二进制方面的一些知识点。 二进制和字节 首先&#xff0c;现代计算机是基于二进制的&#xff0c;从现代计算机电路来说&#xff0c;只有高电平/低电平…

数据在内存中的存储——练习3

题目&#xff1a; 3.1 #include <stdio.h> int main() {char a -128;printf("%u\n",a);return 0; }3.2 #include <stdio.h> int main() {char a 128;printf("%u\n",a);return 0; }思路分析&#xff1a; 首先二者极其相似%u是无符号格式进行…

【Linux】—— 在Linux上进行读写文件操作

前言&#xff1a; 在之前&#xff0c;我已经对进程的相关知识进行了详细的介绍。本期开始&#xff0c;我们将要学习的是关于 “基础I/O”的知识&#xff01;&#xff01;&#xff01; 目录 &#xff08;一&#xff09;C文件接口 &#xff08;二&#xff09;系统文件I/O 1、接…

WebDAV之π-Disk派盘 + BubbleUPnP

BubbleUPnP是一款功能强大的Android播放器,支持UPnP/DLNA多屏互动。它可以将手机内容投屏到电视大屏上,与家人和朋友一起共享。此外,BubbleUPnP还提供了丰富的音乐和影视资源,您可以在线搜索并播放喜欢的内容。 以下是BubbleUPnP的一些主要特点: 1. 支持Chromecast和转码…

WebGL 绘制矩形

上一节绘制了圆点&#xff0c;调用的绘制方法如下&#xff1a;gl.drawArrays(gl.POINTS, 0, 1); 第一个参数明显是个枚举类型&#xff0c;肯定还有其他值&#xff0c;如下所示&#xff1a; POINTS 可视的点LINES 单独线段LINE_STRIP 线条LINE_LOOP 闭合线条TRIANGLES 单独三…