Hive学习之Lateral View

本文详细解析了Hive中Lateralview与UDTF的使用方法,特别是如何结合explode函数处理数组数据,实现数据行化及统计分析。介绍了Lateralview的基本语法、优化及多个LATERALVIEW子句的使用场景。

Lateral view与UDTF函数如explode()一起使用,UDTF对每个输入行产生0或者多个输出行。Lateral view首先在基表的每个输入行应用UDTF,然后连接结果输出行与输入行组成拥有指定表别名的虚拟表。Lateralview的语法如下:

LateralView: LATERAL VIEW udtf(expression) tableAlias AS columnAlias (',' columnAlias)*
fromClause: FROM baseTable (lateralView)*

在Hive-0.6.0之前,Lateral view不支持谓词下推优化,在Hive-0.5.0或者更早的版本中,如果查询中使用了WHERE子句,可能不会被编译,一个措施是在查询前将参数hive.optimize.ppd设置为false。在Hive-0.6.0中修复了该问题,UDTF不支持谓词下推。从Hive-0.12.0开始,可以省略列别名,在这种情况下,别名从UDTF返回的StructObjectInspector的域名继承而来。

下面通过例子来更好地理解Lateral view。假设存在下面的基表pageAds,该表有两列pageid(page的名称)和adid_list(page上出现的广告的数组):

列名称

列类型

pageid

STRING

adid_list

Array<int>

拥有两列的样例表如下,用户想统计出现在所有页面上的某个广告出现的总次数。

pageid

adid_list

front_page

[1, 2, 3]

contact_page

[3, 4, 5]

Lateral view结合explode()可以将adid_list转化为单独的行(explode函数将数组中的每个元素做为一行返回):

SELECT pageid, adid
FROM pageAds LATERAL VIEW explode(adid_list) adTable AS adid; 

输出的结果为:

pageid (string)

adid (int)

"front_page"

1

"front_page"

2

"front_page"

3

"contact_page"

3

"contact_page"

4

"contact_page"

5

要统计特定广告的出现次数,可以使用count和group by:

SELECT adid, count(1)
FROM pageAds LATERAL VIEW explode(adid_list) adTable AS adid
GROUP BY adid;

输出结果为:

int adid

count(1)

1

1

2

1

3

2

4

1

5

1

FROM子句可以有多个LATERAL VIEW子句,后面的LATERALVIEW可以引用出现在LATERAL VIEW左侧的任何表中的列,例如:

SELECT * FROM exampleTable
LATERAL VIEW explode(col1) myTable1 AS myCol1
LATERAL VIEW explode(myCol1) myTable2 AS myCol2;

LATERAL VIEW子句按照出现的顺序依次使用,例如存在下面的基表:

Array<int> col1

Array<string> col2

[1, 2]

[a", "b", "c"]

[3, 4]

[d", "e", "f"]

下面的查询:

SELECT myCol1, col2 FROM baseTable
LATERAL VIEW explode(col1) myTable1 AS myCol1;

输出的结果为:

int mycol1

Array<string> col2

1

[a", "b", "c"]

2

[a", "b", "c"]

3

[d", "e", "f"]

4

[d", "e", "f"]

再增加一个LATERAL VIEW后的查询语句为:

SELECT myCol1, myCol2 FROM baseTable
LATERAL VIEW explode(col1) myTable1 AS myCol1
LATERAL VIEW explode(col2) myTable2 AS myCol2;

输出的结果为:

int myCol1

string myCol2

1

"a"

1

"b"

1

"c"

2

"a"

2

"b"

2

"c"

3

"d"

3

"e"

3

"f"

4

"d"

4

"e"

4

"f"

从Hive-0.12.0开始,支持OUTER LATERALVIEW。当使用OUTRE关键字时可以再LATERAL VIEW不产生行时生成输出行。当UDTF不产生任何行时,比如explode()函数的输入列为空,LATERALVIEW就不会生成任何输出行。在这种情况下原有行永远不会出现在结果中。OUTRE可被用于阻止这种情况,输出行中来自UDTF的列将被设置为NULL。比如下面的语句将生成空的结果集:

SELEC * FROM src LATERAL VIEW explode(array()) C AS a limit 10;

但使用OUTER关键字后:

SELEC * FROM src LATERAL VIEW OUTRE explode(array()) C AS a limit 10;

输出的结果为:

238

val_238

NULL

86

val_86

NULL

311

val_311

NULL

27

val_27

NULL

原文地址:https://blog.csdn.net/skywalker_only/article/details/39289709

推荐阅读:

Hive性能优化(全面)

戳破 | hive on spark 调优点

重要 | mr使用hcatalog读写hive表

重磅:关于hive的join使用必须了解的事情

640

### HiveLATERAL VIEW 的用法 #### 基本概念 `LATERAL VIEW` 是 Hive 提供的一种功能,允许用户通过指定的 UDTF(User Defined Table Generating Function),将复杂的数据结构拆解成多行或多列的形式。它通常与 `EXPLODE` 函数一起使用,用于处理数组或映射等复杂数据类型。 其基本语法如下: ```sql LATERAL VIEW udtf(expression) tableAlias AS columnAlias (',' columnAlias)* ``` 其中: - **udtf**: 用户定义的表生成函数,例如 `EXPLODE` 或自定义函数。 - **expression**: 输入到 UDTF 的表达式,通常是复杂的字段(如数组或映射)。 - **tableAlias**: 别名,表示由 UDTF 生成的结果集。 - **columnAlias**: 表示从 UDTF 输出的每一列的名称[^1]。 --- #### 示例说明 假设有一张员工技能评分表 `employees`,其结构如下: | employee_id | employee_name | skill_ratings | |-------------|---------------|-----------------------| | 1 | Alice | {"Java":5, "Python":4} | | 2 | Bob | {"C++":3, "SQL":5} | 目标是从这张表中提取每位员工的具体技能及其对应的评分。 ##### 查询语句 ```sql SELECT employee_id, employee_name, skill, rating FROM employees LATERAL VIEW EXPLODE(skill_ratings) exploded_table AS skill, rating; ``` ##### 结果解释 在此查询中: - `EXPLODE(skill_ratings)` 将 `skill_ratings` 映射中的键值对逐一展开为两列:`skill` 和 `rating`。 - `exploded_table` 是临时表别名,代表经过 `EXPLODE` 处理后的结果。 - 最终输出的是每条记录被分解后的具体技能和对应评分[^4]。 最终结果如下: | employee_id | employee_name | skill | rating | |-------------|---------------|--------|---------| | 1 | Alice | Java | 5 | | 1 | Alice | Python | 4 | | 2 | Bob | C++ | 3 | | 2 | Bob | SQL | 5 | --- #### INNER VS OUTER 差异 除了普通的 `LATERAL VIEW`,还有一种变体叫作 `LATERAL VIEW OUTER`。两者的主要区别在于如何处理无法匹配的情况。 - 当输入为空或者 UDTF 返回空时: - `LATERAL VIEW`: 不会返回任何行。 - `LATERAL VIEW OUTER`: 即使没有匹配项也会保留原始行,并将其扩展部分设置为 NULL[^2]。 ##### 示例对比 假设有以下数据: | id | skills | |-----|---------------| | 101 | ["A", "B"] | | 102 | [] | ###### 使用 `LATERAL VIEW` ```sql SELECT id, skill FROM test_data LATERAL VIEW explode(skills) t AS skill; ``` 结果: | id | skill | |-----|-------| | 101 | A | | 101 | B | 注意:ID=102 被忽略,因为它没有任何技能。 ###### 使用 `LATERAL VIEW OUTER` ```sql SELECT id, skill FROM test_data LATERAL VIEW OUTER explode(skills) t AS skill; ``` 结果: | id | skill | |-----|-------| | 101 | A | | 101 | B | | 102 | NULL | 可以看到,即使 ID=102 没有技能,仍然会被保留并显示为 NULL。 --- #### 总结 `LATERAL VIEW` 是一种强大的工具,能够帮助我们轻松实现复杂数据类型的解析和转换操作。无论是简单的数组还是嵌套的映射结构,都可以借助此特性完成高效的数据处理任务[^3]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值