Hive UDTF、窗口函数、自定义函数

news2024/11/28 4:28:00

目录

1 UDTF

1.1 概述

1.2 explode

1.3 posexplode

1.4 inline

1.5 Lateral View

2 窗口函数(开窗函数)

2.1 定义

2.2 语法

2.2.1 语法--函数

2.2.2 语法--窗口

 2.2.3 常用窗口函数

3 自定义函数

3.1 基本知识

3.2 实现自定义函数

3.2.1 创建Maven项目

 3.2.2 创建临时函数

3.2.3 创建永久函数


1 UDTF

1.1 概述

UDTF ( Table-Generating Functions),又被称为炸裂函数,接收一行数据,输出一行或多行数据。

1.2 explode

参数

explode(Map<K,V> m)

语法

select explode(`array`(1,2,3,4)) num;

1.3 posexplode

参数

posexplode(ARRAY<T> a)

语法

select posexplode(`array`(1,2,3,4)) as(pos,value);

1.4 inline

参数

inline(ARRAY<STRUCT<f1:T1,...,fn:Tn>> a)

语法        

select inline(
    `array`(
        named_struct(
            "id",1,
            "name","lala",
            "st", named_struct("z",1)),
        named_struct(
            "id",2,
            "name","lala2",
            "st",named_struct("z",2))))
as (`学号`,`姓名`,`struct`);

1.5 Lateral View

定义:Latera View 通常与UDTF配合使用。Lateral View可以将UDTF应用到源表的每行数据,将每行数据转换为一行或多行,并将源表中每行的输出结果与该行连接起来,形成一个虚拟表。

 语法

        (数据准备)

create table stu(
    id int,
    name string,
    hobbies array<string>
)
row format delimited fields terminated by "\t";

set mapreduce.framework.name=local;

select * from stu;
insert into stu values (3,"zs3",`array`("reading","singing"));
insert into stu values (4,"ls4",`array`("dancing","basketball"));

 语法

select id, name, hobbies, hobby
from stu lateral view explode(hobbies) tmp as hobby;

2 窗口函数(开窗函数)

2.1 定义

        窗口函数,能为每行数据划分一个窗口,然后对窗口范围内的数据进行计算,最后将计算结果返回给该行数据。

2.2 语法

        窗口函数的语法中主要包括“窗口”和“函数”两部分。其中“窗口”用于定义计算范围,“函数”用于定义计算逻辑。

基本语法如下:

select 
    order_id,  
    order_date,  
    amount,  
    函数(amount) over (窗口范围) total_amount
    from order_info; 

2.2.1 语法--函数

绝大多数的聚合函数都可以配合窗口使用,例如max(),min(),sum(),count(),avg()等。

select 
    order_id, 
    order_date, 
    amount, 
    sum(amount) over (窗口范围) total_amount
from order_info; 

请思考:若窗口范围是上一行到当前行,该查询语句的结果是什么?

2.2.2 语法--窗口

窗口范围的定义分为两种类型,一种是基于的,一种是基于的。

1)基于行

开始条件不同,结束条件会有不同的选择(参照相同颜色框) 

 

  •  order by [column]:排序
  • unbounded preceding:窗口内第一行
  • unbounded following:窗口内最后一行
  • [num] preceding:前面第num行
  • [num] following:后面第num行
  • current row:当前行
select 
    order_id, 
    order_date, 
    amount, 
    sum(amount) over (order by order_date rows between unbounded preceding and current row) total_amount
from order_info; 

2)基于值(使用较少)

select 
    order_id, 
    order_date, 
    amount, 
    sum(amount) over (order by order_date range between unbounded preceding and current row) total_amount
from order_info; 

3)分区

定义窗口范围时,可以指定分区字段,每个分区单独划分窗口。

 该示例划分窗口范围时,将数据划分为了“黄”“绿”两个区。

select 
    order_id, 
    order_date, 
    amount, 
    sum(amount) over (partition by user_id order by order_date rows between unbounded preceding and current row) total_amount
from order_info; 

 4)缺省

        over( ) 中的三部分内容partition byorder by(rows|range) between … and … 均可省略不写。

① partition by省略不写,表示不分区

② order by 省略不写,表示不排序

(rows|range) between … and … 省略不写,则使用其默认值,默认值如下:

over()包含order by,则默认值为

range between unbounded preceding and current row

over()不包含order by,则默认值为

rows between unbounded preceding and unbounded following

select 
    order_id, 
    order_date, 
    amount, 
    sum(amount) over (partition by user_id order by order_date) total_amount
from order_info; 

 2.2.3 常用窗口函数

按照功能,常用窗口可划分为如下几类:聚合函数、跨行取值函数、排名函数。

1)聚合函数

max:最大值。

min:最小值。

sum:求和。

avg:平均值。

count:计数。

2)跨行取值函数

1leadlag

功能:获取当前行的上/下边某行、某个字段的值。

lag表示前,lead表示后边

select 
    order_id, 
    user_id,
    order_date, 
    amount, 
    lag(order_date,1, '1970-01-01') over (partition by user_id order by order_date) last_date,
    lead(order_date,1, '9999-12-31') over (partition by user_id order by order_date) next_date
from order_info; 

 注:laglead函数不支持自定义窗口。

2first_valuelast_value

功能:获取窗口内某一列的第一个值/最后一个值

select
    order_id,
    user_id,
    order_date,
    amount,
    first_value(order_date,false) over (partition by user_id order by order_date) first_date,
    last_value(order_date,false) over (partition by user_id order by order_date) last_date
from order_info;

3)排名函数

功能:计算排名

select 
    stu_id, 
    course,
    score,
    rank() over(partition by course order by score desc) rk,
    dense_rank() over(partition by course order by score desc) dense_rk,
    row_number() over(partition by course order by score desc) rn
from score_info; 

注:rank dense_rankrow_number不支持自定义窗口。

3 自定义函数

3.1 基本知识

1Hive自带了一些函数比如max/min但是数量有限自己可以通过自定义UDF来方便的扩展。

2Hive提供的内置函数无法满足你的业务处理需要时此时就可以考虑使用用户自定义函数UDFuser-defined function

3)根据用户自定义函数类别分为以下三种:

(1)UDF(User-Defined-Function)

         一进一出。

(2)UDAF(User-Defined Aggregation Function)

         用户自定义聚合函数,多进一出。

         类似于:count/max/min

(3)UDTF(User-Defined Table-Generating Functions)

         用户自定义表生成函数,一进多出。

         如lateral view explode()

4官方文档地址

https://cwiki.apache.org/confluence/display/Hive/HivePlugins

5)在实际中自定义函数使用次数较少,且在使用时,通常定义单行函数

3.2 实现自定义函数

自定义一个UDF实现计算给定基本数据类型的长度为例,这里只讲使用方法,而不是函数逻辑

3.2.1 创建Maven项目

1)导入以下依赖

<dependency>
    <groupId>org.apache.hive</groupId>
    <artifactId>hive-exec</artifactId>
    <version>3.1.3</version>
</dependency>

2)创建类

import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;

public class MyLength extends GenericUDF {
	@Override
	public ObjectInspector initialize(ObjectInspector[] args) throws UDFArgumentException {
		// 在运行sql时,运行当前函数之前调用一次initialize
		// ObjectInspector对象检查器 校验参数个数
		if (args.length != 1) {
			throw new UDFArgumentException("只接受一个参数");
		}

		// 参数类型校验
		ObjectInspector arg = args[0];
		if (ObjectInspector.Category.PRIMITIVE != arg.getCategory()) {
			throw new UDFArgumentException("只接受基本数据类型的参数");
		}

		// 参数类型校验
		PrimitiveObjectInspector primitiveObjectInspector = (PrimitiveObjectInspector) arg;
		if (primitiveObjectInspector.getPrimitiveCategory() != PrimitiveObjectInspector.PrimitiveCategory.STRING) {
			throw new UDFArgumentException("只接受String类型的参数");
		}

		// 返回整数类型
		return PrimitiveObjectInspectorFactory.javaIntObjectInspector;
	}

	@Override
	public Object evaluate(DeferredObject[] args) throws HiveException {
		// 每处理一行数据,调用一次evaluate
		// 不用再校验参数

		DeferredObject arg = args[0];
		Object o = arg.get();// 获取到数据

		if (o == null) { // 行内数据可能为null
			return 0;
		} else {
			return o.toString().length();
		}
	}

	@Override
	public String getDisplayString(String[] strings) {
		// 使用explain后,在执行计划中展示的东西
		// 一般不用写
		return null;
	}
}

 3.2.2 创建临时函数

当前会话断了,就无法在使用

1)打包并上传到Hive所在的服务器

  • 打包

  •  上传

2)将jar包添加到hive的classpath,临时生效

add jar /opt/module/hive-3.1.3/data/length.jar;

3)创建临时函数与开发好的java class关联

create temporary function my_len
as "MyLength";   -- 这里是全限定路径名

 4)在hql中使用自定义的临时函数

3.2.3 创建永久函数

注意:因为add jar本身也是临时生效,所以在创建永久函数的时候,需要制定路径(并且因为元数据的原因,这个路径还得是HDFS上的路径)。

1) 上传length.jar到hdfs

 2) 创建永久函数

create function my_len
as "MyLength"
using jar "hdfs://hadoop102:8020/udf/length.jar";

3)使用永久函数

 创建了永久函数之后,会在函数名之前加上数据库的名称,在functions库中使用该函数直接用my_len(),其它数据库使用该函数则需要加上数据库名,例如functions.my_len()

functions数据库

 其它数据库

 (my_len爆红是因为DataGrip的bug)

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

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

相关文章

RestClient操作文档

RestClient操作文档5.RestClient操作文档5.1.新增文档5.1.1.索引库实体类5.1.2.语法说明5.1.3.完整代码5.2.查询文档5.2.1.语法说明5.2.2.完整代码5.3.删除文档5.4.修改文档5.4.1.语法说明5.4.2.完整代码5.5.批量导入文档5.5.1.语法说明5.5.2.完整代码5.6.小结5.RestClient操作…

JavaSE学习进阶day04_02 Calendar类

第三章 Calendar类 3.1 概述 java.util.Calendar类表示一个“日历类”&#xff0c;可以进行日期运算。它是一个抽象类&#xff0c;不能创建对象&#xff0c;我们可以使用它的子类&#xff1a;java.util.GregorianCalendar类。 有两种方式可以获取GregorianCalendar对象&#…

《Advanced R》学习笔记 | Chapter3 Vectors

专注系列化、高质量的R语言教程推文索引 | 联系小编 | 付费合集本篇推文是学堂君学习第3章“Vectors”的笔记&#xff0c;原文链接是https://adv-r.hadley.nz/vectors-chap.html&#xff0c;可在文末“阅读原文”处直达。通过本章的学习&#xff0c;我们可以更清晰地理解R语言中…

IDPChat:探索基于LLaMA和Stable Diffusion的「开源」中文多模态AI大模型

中文多模态模型 IDPChat 和大家见面了。 随着GPT4、文心一言等的发布&#xff0c;预训练大模型正式开启由单模态向多模态模型演进。多模态的特性为语言模型带来更加丰富的应用场景。 我们认为&#xff0c;未来的AI应用将主要以大模型为核心基石。 而在大模型的领域&#xff0c;…

PFTL101A 2.0KN 3BSE004172R1控制卷取物体时保持物体相互拉长或者绷紧的力

PFTL101A 2.0KN 3BSE004172R1控制卷取物体时保持物体相互拉长或者绷紧的力 ​ 基于单片机的放卷机张力控制系统设计 张力控制&#xff0c;通俗地讲&#xff0c;就是要控制卷取物体时保持物体相互拉长或者绷紧的力。张力应用于最广泛的造纸、纤维、塑料薄膜、电线、印刷品、磁带…

基于SpringBoot的健身房管理系统

有需要请私信或看评论链接哦 可远程调试 基于SpringBoot健身房管理系统一 介绍 此健身房管理系统基于SpringBoot开发&#xff0c;数据库mysql&#xff0c;前端startbootstrap。系统角色分为用户和管理员。用户登录后可查看个人信息&#xff0c;课程报名和课程查询&#xff0c;…

react-5 高阶组件 (HOC)(防抖节流) --- 高阶函数(HOF)(拖拽)

高阶函数&#xff1a;指一类函数,防抖&#xff0c;节流 防抖&#xff1a; 短时间内频繁触发同一事件时&#xff0c;只有最后一次生效. 例如电梯关门的效果 节流&#xff1a; 短时间内频繁触发同一个事件时&#xff0c;在单位时间内&#xff0c;只生效一次。例如lol英雄的大招…

【SpringBoot】面试组合技-天羽屠龙舞,SpringBootApplication注解的作用是什么?SpringBoot怎么实现自动装配的?

SpringBoot源码下载地址&#xff1a;https://github.com/spring-projects/spring-boot/tags 文章目录&#x1f35f;下载源码&#x1f357;环境准备&#x1f356;注解解析&#x1f35d;SpringBootConfiguration注解&#x1f35b;EnableAutoConfiguration注解&#x1f364;AutoC…

Kettle7.0同步数据(简单操作步骤hive-hive)

一、Kettle说明介绍和原理说明 Kettle是一款免费的ETL工具。 ETL分别是“Extract”、“ Transform” 、“Load”三个单词的首字母缩写&#xff0c;也就是代表ETL过程的三个最主要步骤&#xff1a;“抽取”、“转换”、“装载”&#xff0c;但我们平时往往简称其为数据抽取。 ET…

opencv:了解Shi-Tomasi角点检测器及其使用

目标 在本章中,我们将学习另一种角点检测器:Shi-Tomasi角点检测器,并且探索函数cv.goodFeaturesToTrack()的使用方法。 理论 在上一章中,我们学习了Harris角点检测器。后来,在1994年,石屹和托马斯对其进行了一些小的修改,提出了《Good Features to Track》这篇论文,相…

矩阵转置(函数)(C语言实现)

【题目描述】 写一个函数&#xff0c;将一个n*n&#xff08;n<10&#xff09;的二维数组进行转置&#xff0c;即行列交换。要求在主函数中完成输入和输出。 【输入说明】 输入第一行只包括1个数字&#xff0c;表示n&#xff0c;接下来有n行&#xff0c;每行有n个整数。 …

[Java]Session机制

什么是Session Session是另一种记录客户状态的机制&#xff0c;不同的是Cookie保存在客户端浏览器中&#xff0c;而Session保存在服务器上。客户端浏览器访问服务器的时候&#xff0c;服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需…

基于springboot和ajax的简单项目 04.html文件的js用来分页功能,有专门的分页页面html文件(下)

01&#xff0c;因为分页的功能是很多场景都需要使用的&#xff0c;所以可以单独提出来&#xff0c;到时候加载到相关html的div中就好了。 最开始初始化分页html文件&#xff08;page.html&#xff09;的全部代码&#xff1a;&#xff08;直接使用的是ul&#xff0c;li&#xff…

LeetCode算法小抄--快速排序详解及应用

LeetCode算法小抄--快速排序详解及应用快速排序详解及应用代码实现快速选择算法&#xff08;Quick Select&#xff09;-- 变体[215. 数组中的第K个最大元素](https://leetcode.cn/problems/kth-largest-element-in-an-array/)[剑指 Offer II 076. 数组中的第 k 大的数字](https…

LCMXO2-2000HC-4FTG256I FPGA lattice 深力科MachXO2系列超低功耗非易失PLD器件特性及原理图

LCMXO2-2000HC-4FTG256I FPGA lattice 深力科MachXO2系列超低功耗非易失PLD器件特性及原理图 lattice莱迪斯深力科电子 MachXO2系列 LCMXO2-2000HC-4FTG256I 超低密度FPGA现场可编程门阵列&#xff0c;适用于低成本的复杂系统控制和视频接口设计开发&#xff0c;满足了通信、计…

std::condition_variable::wait_for 的几个细节

std::condition_variable::wait_for 的两种重载用法https://blog.csdn.net/smalbig/article/details/130152253 &#xff08;以下简称上篇&#xff09;直观上介绍了 std::condition_variable::wait_for 的使用效果&#xff0c;这篇对没解释清楚的注释、执行结果进行解释。 1.…

大话 HTTP 协议前世今生

HTTP 全称 Hypertext Transfer Protocol&#xff0c;中文是超文本传输协议。网上讲 HTTP 协议的资料可以说是五花八门&#xff0c;但大多数都在罗列 HTTP 协议具体的规定&#xff0c;很少有讲 HTTP 协议这样设计的原因。今天我就尝试从解决问题的角度分析 HTTP 协议主要特性&am…

Android init学习笔记

init大体介绍 init是Android启动的第一个用户空间进程&#xff0c;它fork产生一些关键进程&#xff0c;如zygote、surfaceflinger进程。 init进程有很多功能&#xff1a;加载内核模块、挂载系统分区、加载sepolicy、支持属性服务、启动rc脚本、执行事件触发器和属性改变等等 …

C++之深入解析STL deque容器的底层实现原理

一、deque 容器的存储结构 事实上&#xff0c;STL 中每个容器的特性&#xff0c;和它底层的实现机制密切相关&#xff0c;deque 自然也不例外&#xff0c;deque 容器擅长在序列的头部和尾部添加或删除元素。想搞清楚 deque 容器的实现机制&#xff0c;需要先了解 deque 容器的…

【Python】实战:生成有关联单选问卷 csv《营养不良风险评估表》

目录 一、适用场景 二、业务需求 三、Python 文件 &#xff08;1&#xff09;创建文件 &#xff08;2&#xff09;示例代码 四、csv 文件 &#xff08;1&#xff09;营养不良风险评估表&#xff08;问题 6 不选“不能取得”&#xff09; &#xff08;2&#xff09;营养…