HIVE函数之行转列、列转行、分组排序取TopN

博客围绕Hive数据处理展开,介绍了分组排序取TopN,计算班级中单科排名前三名学生姓名;还阐述了行转列,即将多行数据转成一列,以及列转行,把一列数据转成多行的操作,包含建表、导入数据及具体语句实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、分组排序取TopN

我们的需求是这样,有一份学生的考试分数信息,语文、数学、英语这三门,需要计算出班级中单科排名 前三名学生的姓名

1、建表并导入数据

create external table student_score(
id int,
name string,
sub string,
score int
)row format delimited
fields terminated by '\t'
location '/data/student_score';

hdfs dfs -put /data/soft/hivedata/student_score.data /data/student_score

 2、组内分组并按照分数排序

select  *,row_number() over(partition by sub order by score desc) num 
from student_score

 3、每组取前三名

select  * from(
select  *,row_number() over(partition by sub order by score desc) num from student_score
) s where s.num<=3    

4、备注

  • row_number over() 是正常排序
  • rank() over()是跳跃排序,有两个第一名时候,接下来就是第三名(在各个分组内)
  • dense_rank() over() 是连续排序,有两个第一名的时候,依旧跟着第二名(在各个分组内)

二、行转列

1、行转列就是把多行的数据转成一列数据

  • CONCAT_WS() :可以实现根据指定的分隔符拼接多个字段的值,最终转换成带有分隔符的字符串,它可以接受多个参数,第一个是分隔符,后面的参数可以是字符串或是字符串数组,最终就是使用分隔符吧后面的字符串拼到一块
  • COLLECT_SET() :这个函数可以返回一个set集合
  • COLLECT_LIST():这个函数可以返回一个list集合

2、建表并导入数据

create external table student_favors(
name string,
favor string
)row format delimited
fields terminated by '\t'
location '/data/student_favors';

hdfs dfs -put /data/soft/hivedata/student_favors.data  /data/student_favors

3、语句:

3.1、 先把多列数据转成一行数据

  select name,concat_ws(',',collect_list(favor)) as favor_list
  from student_favors group by name;

3.2、把list字段转成换string类型

  select name,concat_ws(',',collect_list(favor)) as favor_list 
  from student_favors group by name;

 三、列转行

1、列转行可以把一列数据转成多行

  • split() :接收一个字符串和切割规则,使用切割规则对数据的行进行切割,最终返回一个array数组
  • explode(array) :表示把数组的每个元素转成一行
  • explode(map) :表示把map中每个key-value转成一行,key为一列,value为一行
  • lateral view :对数据产生一个支持别名的虚拟表

2、建表并导入数据

create external table student_favors_2(
name string,
favorlist string
)row format delimited
fields terminated by '\t'
location '/data/student_favors_2';

hdfs dfs -put /data/soft/hivedata/student_favors_2.data /data/student_favors_2

3、语句

3.1  先使用split对favorlist字段进行切割

select split(favorlist,',') from student_favors_2;

 3.2 再使用explode对数据进行操作

select explode(split(favorlist,',')) from student_favors_2;

3.3 laterview相相当于把explode返回的数据作为一个虚拟表来使用了,起名字为table1,然后给这个表里面的 那一列数据起一个名字叫favor_new,如果有多个字段,可以再后面指定多个。这样在select后面就可以 使用这个名字了,有点类似join操作了 

select name,favor_new from student_favors_2 lateral view explode(split(favorlist,','))table1 as favor_new;

<think>好的,我现在需要帮助用户了解Hive中行转列转行的实现方法和语法。用户已经提供了一些相关的引用资料,我需要先仔细阅读这些资料,然后整理出一个清晰的回答结构。 首先,行转列转行Hive中是比较常见的操作,尤其是在处理复杂的数据结构如数组或映射时。根据引用中的内容,行转列通常使用lateral view配合explode函数,而转行则可能涉及到聚合函数如collect_list或concat_ws。 对于行转列,引用[2]和[3]提到,explode函数可以将数组或映射拆分成多行,结合lateral view可以处理多的情况。例如,split函数将字符串分割成数组,然后通过explode展开。引用中的示例展示了如何将item_sku_id拆分成多行sku_id,这可能就是用户需要的行转列操作。 转行方面,引用[4]提到了concat_ws函数,可以将多个字符串拼接成一个,结合collect_list这样的聚合函数,可以把多行数据合并成一行。例如,使用collect_list收集数据,再用concat_ws连接起来,形成转行的效果。 接下来,我需要将这两个部分分开解释,分别给出语法和示例,确保用户能够理解具体的用法。同时,要注意用户提到的必须使用中文回答,并且数学表达式需要用$...$格式,但这个问题主要涉及SQL语法,可能数学表达式较少,不过还是要注意如果有的话要正确应用。 另外,用户要求生成相关问题,我需要根据行转列转行的主题,提出一些可能的相关问题,比如explode和posexplode的区别,如何处理空值,或者性能优化的方法等。 检查是否有遗漏的部分,比如是否提到了posexplode的使用,这在引用[2]中有提到,可以补充在行转列的相关内容里。同时,注意示例代码的正确性,确保语法正确,比如正确的Hive SQL语句结构,使用lateral view的位置是否正确。 最后,确保回答结构清晰,分点说明,每个部分都有示例代码,并且引用的标注正确。比如在解释行转列时,引用[1][2][3],转行时引用[3][4]。 现在需要把这些整理成用户友好的回答,分步骤解释行转列转行的实现方法,每个步骤附上示例,并生成相关问题。</think>### Hive转列转行实现方法 #### 一、行转列(多行转单) 将多行数据合并为单数据,常用聚合函数结合字符串拼接实现。 **语法与示例** ```sql -- 使用collect_list聚合后拼接 SELECT order_id, CONCAT_WS(',', COLLECT_LIST(sku_id)) AS sku_list FROM table_name GROUP BY order_id; ``` **示例数据转换** 输入: | order_id | sku_id | |----------|--------| | 1001 | A | | 1001 | B | 输出: | order_id | sku_list | |----------|----------| | 1001 | A,B | **关键函数** - `COLLECT_LIST()`: 聚合数据为数组[^3] - `CONCAT_WS()`: 使用分隔符拼接数组元素[^4] #### 二、转行(单转多行) 将单中的复杂结构拆分为多行,核心使用`LATERAL VIEW`+`explode`组合。 **语法与示例** ```sql -- 拆分字符串为多行 SELECT order_id, sku_id FROM table_name LATERAL VIEW EXPLODE(SPLIT(sku_list, ',')) adTable AS sku_id; ``` **示例数据转换** 输入: | order_id | sku_list | |----------|----------| | 1001 | A,B | 输出: | order_id | sku_id | |----------|--------| | 1001 | A | | 1001 | B | **扩展用法** 1. **数组处理** ```sql SELECT EXPLODE(ARRAY(1,2,3)) AS num; -- 输出3行数字 ``` 2. **带位置索引的拆分** ```sql SELECT POSEXPLODE(SPLIT('a,b,c', ',')) AS (pos, item); -- 输出带位置序号的结果 ``` 3. **Map类型处理** ```sql SELECT EXPLODE(MAP('k1','v1','k2','v2')) AS (key,value); -- 输出两key/value[^2] ``` **注意要点** - 使用`LATERAL VIEW`时必须指定别名[^1] - `explode`不能直接与其他非炸裂字段共存,必须通过`LATERAL VIEW`关联[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值