当前位置: 首页 > news >正文

HIVE的高频面试UDTF函数

文章目录

  • 1. UDTF是什么
  • 2. 典型函数explode
  • 3. 案例实操
    • 3.1 业务需求
    • 3.2 业务开发
    • 3.3 补充转义


1. UDTF是什么

表生成函数

  • 特点: 一进多出的函数
  • 比如: explode(爆炸函数)
  • 此类函数以后学习一个记住一个即可

2. 典型函数explode

explode函数接收map或者array类型的数据作为参数,然后把参数中的每个元素炸开变成一行数据。一个元素一行。这样的效果正好满足于输入一行输出多行

explode(array)将array列表里的每个元素生成一行;
explode(map)将map里的每一对元素作为一行,其中key为一列,value为一列;

3. 案例实操

3.1 业务需求

我们已有数据如下

idname
10CLARK|KING|MILLER
20SMITH|JONES|SCOTT|ADAMS|FORD
30ALLEN|WARD|MARTIN|BLAKE|TURNER|JAMES

我们想要的结果
在这里插入图片描述
我们该如何实施?

3.2 业务开发

第一步: 在node1的/root/hivedata/下, 创建一个dept.txt文件, 添加以下数据:

10      CLARK|KING|MILLER
20      SMITH|JONES|SCOTT|ADAMS|FORD
30      ALLEN|WARD|MARTIN|BLAKE|TURNER|JAMES

第二步: 在hive中创建表

create database day04_hive;
use day04_hive;
create table day04_hive.dept(dept_id int,dept_name array<string>
)row format 
delimited fields terminated by '\t'
collection items terminated by '|';

第三步: 导入数据到 dept表中

load data local inpath '/root/hivedata/dept.txt' into table day04_hive.dept;

第四步: 测试是否加载成功

select * from day04_hive.dept;

显示结果如下

+---------------+----------------------------------------------------+
| dept.dept_id  |                   dept.dept_name                   |
+---------------+----------------------------------------------------+
| 10            | ["CLARK","KING","MILLER"]                          |
| 20            | ["SMITH","JONES","SCOTT","ADAMS","FORD"]           |
| 30            | ["ALLEN","WARD","MARTIN","BLAKE","TURNER","JAMES"] |
+---------------+----------------------------------------------------+

尝试使用explode:

select  explode(dept_name) from day04_hive.dept;

结果为:

+---------+
|   col   |
+---------+
| CLARK   |
| KING    |
| MILLER  |
| SMITH   |
| JONES   |
| SCOTT   |
| ADAMS   |
| FORD    |
| ALLEN   |
| WARD    |
| MARTIN  |
| BLAKE   |
| TURNER  |
| JAMES   |
+---------+

接着尝试, 将 部门id加上:

select  dept_id,explode(dept_name) as dept_name from day04_hive.dept;

发现, 报错了:

Error: Error while compiling statement: FAILED: SemanticException [Error 10081]: UDTF's are not supported outside the SELECT clause, nor nested in expressions (state=42000,code=10081)

在这里插入图片描述
UDTF函数特殊要求:

  1. 如果UDTF函数被使用在select后面, 不允许在出现其他的列或者字段
  2. UDTF函数不允许被其他的函数所嵌套, 但是他可以嵌套其他的函数

如何解决呢? 可以将这个结果作为临时表 ,然后和原有表进行关联即可
但是发现, 好像无法关联, 因为临时表和原有表没有关联条件, 此时如何办呢?
答: hive为了解决这种问题, 可以采用侧视图的方案, 而侧视图一般就是和UDTF配合使用, 解决UDTF函数特殊问题
侧视图: LATERAL VIEW

用法:lateral view udtf(expression) tableAlias AS columnAlias
放置位置: 在SQL的最后面

接下来, 使用侧视图解决问题:

select  dept_id, name from day04_hive.dept lateral view  explode(dept_name) t1 as name;+----------+---------+
| dept_id  |  name   |
+----------+---------+
| 10       | CLARK   |
| 10       | KING    |
| 10       | MILLER  |
| 20       | SMITH   |
| 20       | JONES   |
| 20       | SCOTT   |
| 20       | ADAMS   |
| 20       | FORD    |
| 30       | ALLEN   |
| 30       | WARD    |
| 30       | MARTIN  |
| 30       | BLAKE   |
| 30       | TURNER  |
| 30       | JAMES   |
+----------+---------+

思考: 如果刚刚建表的时候, 不使用array类型, 使用string类型, 如何解决呢?

select  dept_id, name from day04_hive.dept lateral view  explode(split(dept_name,'|')) t1 as name;

同样的我们重复前面建表的操作再建立一个表,建表语句如下

create table day04_hive.dept1(dept_id int,dept_name string
)row format delimited
fields terminated by '\t';

加载数据

load data local inpath '/root/hivedata/dept.txt' into table day04_hive.dept1;

使用explode将其炸开

select dept_id,t2.name from day04_hive.dept1 lateral view explode(split(dept_name,'|')) t2 as name;

结果如下,这是怎么回事?
在这里插入图片描述
这显然不是我们想要的,这是因为
split(dept_name,‘|’) 中的 | 在正则表达式中表示"或"操作,所以它会按照每个字符进行分割,导致:

“CLARK” 被分割成 [“C”, “L”, “A”, “R”, “K”]
“KING” 被分割成 [“K”, “I”, “N”, “G”]
“MILLER” 被分割成 [“M”, “I”, “L”, “L”, “E”, “R”]
然后 explode() 再对每个字母进行展开,就变成了一行一个字母。

这意味着我们需要转义符,使用双反斜杠转义(推荐)

select dept_id,t2.name from day04_hive.dept1 lateral view explode(split(dept_name,'\\|')) t2 as name;

在这里插入图片描述
出现了我们想要的结果,大功告成。

3.3 补充转义

解决方案
您需要对 | 进行转义,有以下几种方法:

方法1:使用双反斜杠转义(推荐)

SELECT explode(split(dept_name, '\\|')) FROM dept1;

方法2:使用方括号转义

SELECT explode(split(dept_name, '[|]')) FROM dept1;

方法3:使用字符类转义

SELECT explode(split(dept_name, '\\|')) FROM dept1;

在这里插入图片描述

如果有帮助到你,请点赞收藏

http://www.dtcms.com/a/351709.html

相关文章:

  • 【软考论文】论面向对象建模方法(动态、静态)
  • 无人机倾斜摄影农田航线规划
  • HTML应用指南:利用GET请求获取中国银行人民币存款利率数据
  • SciPy科学计算与应用:SciPy线性代数模块入门-矩阵运算与应用
  • 精确位置定位,AR交互助力高效作业流程​
  • 余承东:鸿蒙智行累计交付突破90万辆
  • 机器人视频感知架构深度解析:7条技术法则,打造低延迟实时感知与交互
  • 【ROS2】 忽略局域网多机通信导致数据接收的bug
  • 天气查询小程序项目报告
  • iOS 审核 4.3a【二进制加固】
  • Spring MVC 全解析:从核心原理到 SSM 整合实战 (附完整源码)
  • leetcode-python-383赎金信
  • 深度学习----由手写数字识别案例来认识PyTorch框架
  • 构建AI智能体:十四、从“计算”到“洞察”:AI大模型如何让时间序列数据“开口说话”
  • version GLIBCXX_3.4.30‘ not found (required by cmake)
  • JVM线上调优参数配置指南
  • 今日分享:C++ string 类模拟实现
  • 深度学习之第四课卷积神经网络CNN(一)
  • 不卡顿、不掉线!稳定可靠的体育赛事直播系统源码解析
  • 【Chrome】更新后白屏无法显示问题
  • 【力扣】面试经典150题总结04-区间/栈
  • python 自学笔记13 numpy数组规整
  • 智能驾驶机器学习知识总结
  • 越过千万生死线,鸿蒙直面商业化考验
  • ME_INFORECORD_MAINTAIN_MULTI,创建采购单信息记录,报错ME 816 系统错误(方法PROCESS_CONDITION中错误)
  • Feign 调用为服务报 `HardCodedTarget(type=xxxClient, name=xxxfile, url=http://file)`异常
  • 关于C#中运算符的简单说明
  • 为什么的中小企业很难承受“大型系统”的成本
  • 【RAGFlow代码详解-10】文本处理和查询处理
  • 深度学习(五):正则化:约束模型的复杂度