news 2026/8/25 19:55:56

Hive explode巨详细讲解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Hive explode巨详细讲解

一、explode是什么?

Hive 中的explode用于把一行中的数组或 Map 拆成多行。

一行数组 ↓ explode 多行普通字段

例如原始数据:

user_id | tags --------|------------------ 1 | ["hive", "spark"] 2 | ["flink", "java"]

展开后:

user_id | tag --------|------ 1 | hive 1 | spark 2 | flink 2 | java

二、展开数组

Hive 中通常需要配合LATERAL VIEW使用:

SELECTuser_id,tagFROMuser_tags LATERALVIEWEXPLODE(tags)tAStag;

其中:

EXPLODE(tags):展开 tags 数组 t :虚拟表别名 AS tag :定义展开后的字段名

如果一行数组中有 3 个元素,该行通常会变成 3 行。


三、完整示例

1. 建表示例

CREATETABLEuser_tags(user_idBIGINT,tags ARRAY<STRING>)STOREDASORC;

2. 查询数组元素

SELECTuser_id,tagFROMuser_tags LATERALVIEWEXPLODE(tags)tAStag;

3. 展开后统计每个标签的用户数

SELECTtag,COUNT(DISTINCTuser_id)ASuser_countFROMuser_tags LATERALVIEWEXPLODE(tags)tAStagGROUPBYtag;

注意:如果同一个用户的数组中重复出现同一个标签,直接COUNT(*)可能会重复计数;统计用户数时通常使用COUNT(DISTINCT user_id)


四、字符串转数组后再展开

如果字段不是数组,而是逗号分隔的字符串:

user_id | tags --------|---------------- 1 | hive,spark,flink 2 | java,hadoop

可以先用split()转成数组,再使用explode()

SELECTuser_id,tagFROMuser_tags LATERALVIEWEXPLODE(SPLIT(tags,','))tAStag;

结果:

user_id | tag --------|------- 1 | hive 1 | spark 1 | flink 2 | java 2 | hadoop

如果分隔符是竖线,由于split的分隔符是正则表达式,需要转义:

LATERALVIEWEXPLODE(SPLIT(tags,'\\|'))tAStag;

五、展开 Map

explode()也可以展开 Map,结果会得到两个字段:keyvalue

原始数据:

user_id | attributes --------|----------------------------- 1 | {"city":"Beijing","age":"20"}

SQL:

SELECTuser_id,attr_key,attr_valueFROMuser_attributes LATERALVIEWEXPLODE(attributes)tASattr_key,attr_value;

结果:

user_id | attr_key | attr_value --------|----------|------------ 1 | city | Beijing 1 | age | 20

六、posexplode:展开并保留下标

如果除了元素值,还需要知道元素在数组中的位置,可以使用posexplode()

SELECTuser_id,pos,tagFROMuser_tags LATERALVIEWPOSEXPLODE(tags)tASpos,tag;

结果:

user_id | pos | tag --------|-----|------ 1 | 0 | hive 1 | 1 | spark 2 | 0 | flink 2 | 1 | java

Hive 数组下标从0开始。

常见用途:

  • 保留数组原始顺序;
  • 获取元素所在位置;
  • 两个数组按照相同下标进行匹配。

七、两个数组按位置对应

假设表中有:

user_id | subjects | scores --------|------------------|-------- 1 | [math, english] | [90, 85]

目标是得到:

user_id | subject | score --------|---------|------ 1 | math | 90 1 | english | 85

可以分别使用posexplode(),再根据位置关联:

WITHsubject_dataAS(SELECTuser_id,pos,subjectFROMuser_score LATERALVIEWPOSEXPLODE(subjects)tASpos,subject),score_dataAS(SELECTuser_id,pos,scoreFROMuser_score LATERALVIEWPOSEXPLODE(scores)tASpos,score)SELECTs.user_id,s.subject,c.scoreFROMsubject_data sJOINscore_data cONs.user_id=c.user_idANDs.pos=c.pos;

不要直接对两个数组分别explode后放在同一条查询中,否则容易产生笛卡尔积。


八、LATERAL VIEW OUTER EXPLODE

普通的explode()遇到NULL或空数组时,可能不会保留原始行:

SELECTuser_id,tagFROMuser_tags LATERALVIEWEXPLODE(tags)tAStag;

如果希望数组为空时仍保留用户记录,可以使用OUTER

SELECTuser_id,tagFROMuser_tags LATERALVIEWOUTEREXPLODE(tags)tAStag;

没有元素的用户会保留,展开后的tag通常为NULL

两者区别:

LATERAL VIEW EXPLODE:没有元素时可能不输出该行 LATERAL VIEW OUTER EXPLODE:没有元素时仍保留原始行

九、展开数组中的 Struct

如果数组元素是结构体,例如:

orders = [ {product: "apple", price: 5}, {product: "banana", price: 8} ]

表结构:

CREATETABLEuser_orders(user_idBIGINT,orders ARRAY<STRUCT<product:STRING,price:DOUBLE>>)STOREDASPARQUET;

展开并访问 Struct 字段:

SELECTuser_id,order_item.productASproduct,order_item.priceASpriceFROMuser_orders LATERALVIEWEXPLODE(orders)tASorder_item;

十、常见注意事项

1.explode会放大数据量

100 万行 × 每行 100 个数组元素 ≈ 1 亿行输出

使用前要评估数据量和下游计算成本。

2. 注意NULL、空数组和空字符串

这几种情况含义不同:

NULL:没有数组值 []:数组存在,但没有元素 ['']:数组中有一个空字符串

必要时可以过滤空值:

SELECTuser_id,tagFROMuser_tags LATERALVIEWEXPLODE(tags)tAStagWHEREtagISNOTNULLANDtag<>'';

3. 展开后再聚合可能重复计数

展开会改变行数,后续计算指标时要重新确认统计口径。

4.explode通常不能直接放在普通SELECT

推荐写法:

SELECTid,itemFROMtable_name LATERALVIEWEXPLODE(array_col)tASitem;

而不是简单写成:

-- 某些 Hive 版本或场景下不适用SELECTid,EXPLODE(array_col)FROMtable_name;

十一、快速记忆

-- 展开数组LATERALVIEWEXPLODE(array_col)tASitem
-- 展开数组并保留下标LATERALVIEWPOSEXPLODE(array_col)tASpos,item
-- 展开 MapLATERALVIEWEXPLODE(map_col)tASmap_key,map_value
-- 数组为空时保留原始行LATERALVIEWOUTEREXPLODE(array_col)tASitem

一句话总结:

explode用于把 Hive 一行中的数组或 Map 拆成多行;数组展开后得到元素,Map 展开后得到键和值,若需要保留下标则使用posexplode

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/25 19:54:55

电报 Telegram 上骗子多多!套路多多!千万小心不要上当受骗!

重要通知‼️‼️ 广大 Tg 用户&#xff0c;如大家在 Tg 有收到如下图片或者类似检测账户的信息请不要相信⚠️⚠️这些都是盗用 Tg 账户的‼️ 官方检测机器人从不会主动给任何用户发送检测账户或解除账户信息⚠️⚠️ 请大家不要下载官网以外的盗版或老版软件&#xff0c;很多…

作者头像 李华
网站建设 2026/8/25 19:46:14

高效刷LeetCode:从模式识别到面试实战的完整方法论

刷Leetcode&#xff0c;几乎是每个程序员技术生涯的必经之路。但你是否也经历过这样的困境&#xff1a;打开题库&#xff0c;面对上千道题目&#xff0c;不知从何刷起&#xff1b;好不容易刷了几十道&#xff0c;遇到新题还是毫无思路&#xff1b;看着别人分享的“三个月斩获大…

作者头像 李华
网站建设 2026/8/25 19:46:06

从零开始学Coze:AI机器人开发入门与实战指南

1. 从“学扣子”到“Coze”&#xff1a;一个新手必须搞懂的概念变迁如果你最近在社交媒体或者一些技术社区里&#xff0c;看到“学扣子”这个词&#xff0c;感觉一头雾水&#xff0c;但又隐约觉得它和AI、和编程有点关系&#xff0c;那你的直觉是对的。作为一个在AI应用开发领域…

作者头像 李华
网站建设 2026/8/25 19:43:47

AI辅助产品需求文档与原型设计:五步工作流提升PRD输出效率

你是不是也遇到过这样的场景&#xff1f;作为产品经理&#xff0c;接到一个新需求&#xff0c;打开Word或Axure&#xff0c;面对空白文档&#xff0c;从零开始构思PRD&#xff08;产品需求文档&#xff09;&#xff0c;然后还要画原型图。这个过程往往需要几天时间&#xff0c;…

作者头像 李华
网站建设 2026/8/25 19:42:57

什么是巴西ANATEL无线认证

ANATEL Agncia Nacional de Telecomunicaes&#xff0c;巴西国家电信局。 类比&#xff1a;美国 FCC、欧盟 RED、中国进网许可&#xff0c;巴西无线电 / 电信设备强制准入认证&#xff1b;没有 ANATEL&#xff0c;产品不能清关、不能销售&#xff0c;会被扣货罚款。注意&#…

作者头像 李华
网站建设 2026/8/25 19:42:43

UE5 GAS实战:从零构建模块化技能与状态系统

在UE5项目中实现复杂的角色技能、状态效果和属性系统时&#xff0c;你是否曾感到蓝图连线越来越臃肿&#xff0c;逻辑复用困难&#xff0c;多人同步更是让人头疼&#xff1f;Gameplay Ability System&#xff08;GAS&#xff09;正是为解决这些痛点而生的官方解决方案。本文将带…

作者头像 李华