Hive函数(二)

news2024/9/28 13:18:56

1、炸裂函数

1.1、UDTF概述

定义:

UDTF(Table-Generating Functions),接收一行数据,输出一行或多行数据。

 

1.1.1、explode(ARRAY a)

功能:

语法:

 

select explode(array("a","b","c")) as item;

1.1.2、explode(Map m)

功能:

 语法:

select explode(map("a",1,"b",2,"c",3)) as (key,value);

1.1.3、posexplode(ARRAY a)

功能:

 语法:

select posexplode(array("a","b","c")) as (pos,item);

1.1.4、inline(ARRAYf1:T1,...,fn:Tn> a)

功能:

语法:

select inline(array(named_struct("id", 1, "name", "zs"), named_struct("id", 2, "name", "ls"),
                    named_struct("id", 3, "name", "ww"))) as (id, name);

1.2、Lateral View

定义:

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

语法:

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

 

2、案例演示

2.1、数据准备

1)表结构

movie

category

《疑犯追踪》

悬疑,动作,科幻,剧情

《Lie to me》

悬疑,警匪,动作,心理,剧情

《战狼2》

战争,动作,灾难

 2)建表语句


create table movie_info(
    movie string,     --电影名称
    category string   --电影分类
) 
row format delimited fields terminated by "\t";

3)装载语句

insert overwrite table movie_info
values ("《疑犯追踪》", "悬疑,动作,科幻,剧情"),
       ("《Lie to me》", "悬疑,警匪,动作,心理,剧情"),
       ("《战狼2》", "战争,动作,灾难");

2.2、需求

1)需求说明

根据上述电影信息表,统计各分类的电影数量,期望结果如下:

剧情

2

动作

3

心理

1

悬疑

2

战争

1

灾难

1

科幻

1

警匪

1

2)答案

select cate, count(*)
from (
         select movie, cate
         from (
                  select movie, split(category, ',') cates
                  from movie_info) t1 lateral view explode(cates) tmp as cate) t2
group by cate;

3、窗口函数(开窗函数)

3.1、概述

定义:

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

 

语法:

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

基本语法如下:

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

 

语法——函数

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

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

 

语法——窗口

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

数据准备


DROP TABLE IF EXISTS order_info;
create table order_info(
                           `order_id`     string COMMENT '订单id',
                           `user_id`      string COMMENT '用户id',
                           `order_date`  string COMMENT '下单日期',
                           `amount` decimal(16, 2) COMMENT '订单金额'
) COMMENT '订单表'
    ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';


insert overwrite table order_info
values ('1', '1001', '2022-01-01', 10),
       ('2', '1001', '2022-01-02', 20),
       ('3', '1001', '2022-01-03', 10),
       ('4', '1002', '2022-01-04', 30),
       ('5', '1002', '2022-01-05', 40),
       ('6', '1002', '2022-01-06', 20);

3.1.1、窗口—基于行

 

思考:如下基于行的窗口划分方式,查询语句的返回结果是什么?

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

 

3.1.2、窗口—基于值

 

思考:如下基于值的窗口划分方式,是基于哪个字段的值划分的?该查询语句的返回结果是什么?

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

 

3.1.3、窗口—分区

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

 

分区语法如下,请思考:该查询语句的结果是什么?

select order_id,
       user_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;

 

3.1.4、窗口—缺省

over( ) 中的三部分内容partition by、order 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, user_id, order_date, amount, sum(amount) over (partition by user_id order by order_date) total_amount
from order_info;

 

3.2、常用窗口函数

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

1)聚合函数

max:最大值。

min:最小值。

sum:求和。

avg:平均值。

count:计数。

2)跨行取值函数

(1)lead和lag

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

语法:

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;

思考:该查询语句的结果是什么?

 

注:lag和lead函数不支持自定义窗口。

(2)first_value和last_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)排名函数

常用窗口函数——rank、dense_rank、row_number

功能:计算排名


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_rank、row_number不支持自定义窗口。

4、案例演示

4.1、数据准备

1)表结构

order_id

user_id

user_name

order_date

order_amount

1

1001

小元

2022-01-01

10

2

1002

小海

2022-01-02

15

3

1001

小元

2022-02-03

23

4

1002

小海

2022-01-04

29

5

1001

小元

2022-01-05

46

 2)建表语句

DROP TABLE IF EXISTS order_info;
create table order_info
(
    order_id     string, --订单id
    user_id      string, -- 用户id
    user_name    string, -- 用户姓名
    order_date   string, -- 下单日期
    order_amount int     -- 订单金额
);

3)装载语句

insert overwrite table order_info
values ('1', '1001', '小元', '2022-01-01', '10'),
       ('2', '1002', '小海', '2022-01-02', '15'),
       ('3', '1001', '小元', '2022-02-03', '23'),
       ('4', '1002', '小海', '2022-01-04', '29'),
       ('5', '1001', '小元', '2022-01-05', '46'),
       ('6', '1001', '小元', '2022-04-06', '42'),
       ('7', '1002', '小海', '2022-01-07', '50'),
       ('8', '1001', '小元', '2022-01-08', '50'),
       ('9', '1003', '小辉', '2022-04-08', '62'),
       ('10', '1003', '小辉', '2022-04-09', '62'),
       ('11', '1004', '小猛', '2022-05-10', '12'),
       ('12', '1003', '小辉', '2022-04-11', '75'),
       ('13', '1004', '小猛', '2022-06-12', '80'),
       ('14', '1003', '小辉', '2022-04-13', '94');

 

4.2、需求

1)统计每个用户截至每次下单的累积下单总额

(1)期望结果

order_id

user_id

user_name

order_date

order_amount

sum_so_far

1

1001

小元

2022-01-01

10

10

5

1001

小元

2022-01-05

46

56

8

1001

小元

2022-01-08

50

106

3

1001

小元

2022-02-03

23

129

6

1001

小元

2022-04-06

42

171

2

1002

小海

2022-01-02

15

15

4

1002

小海

2022-01-04

29

44

7

1002

小海

2022-01-07

50

94

9

1003

小辉

2022-04-08

62

62

10

1003

小辉

2022-04-09

62

124

12

1003

小辉

2022-04-11

75

199

14

1003

小辉

2022-04-13

94

293

11

1004

小猛

2022-05-10

12

12

13

1004

小猛

2022-06-12

80

92

 (2)需求实现

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

2)统计每个用户截至每次下单的当月累积下单总额

(1)期望结果

order_id

user_id

user_name

order_date

order_amount

sum_so_far

1

1001

小元

2022-01-01

10

10

5

1001

小元

2022-01-05

46

56

8

1001

小元

2022-01-08

50

106

3

1001

小元

2022-02-03

23

23

6

1001

小元

2022-04-06

42

42

2

1002

小海

2022-01-02

15

15

4

1002

小海

2022-01-04

29

44

7

1002

小海

2022-01-07

50

94

9

1003

小辉

2022-04-08

62

62

10

1003

小辉

2022-04-09

62

124

12

1003

小辉

2022-04-11

75

199

14

1003

小辉

2022-04-13

94

293

11

1004

小猛

2022-05-10

12

12

13

1004

小猛

2022-06-12

80

80

(2)需求实现

select order_id,
       user_id,
       user_name,
       order_date,
       order_amount,
       sum(order_amount)
           over (partition by user_id,date_format(order_date,'yyyy-MM') order by order_date rows between unbounded preceding and current row ) sum_so_far
from order_info;

3)统计每个用户每次下单距离上次下单相隔的天数(首次下单按0天算)

(1)期望结果

order_id

user_id

user_name

order_date

order_amount

diff

1

1001

小元

2022-01-01

10

0

5

1001

小元

2022-01-05

46

4

8

1001

小元

2022-01-08

50

3

3

1001

小元

2022-02-03

23

26

6

1001

小元

2022-04-06

42

62

2

1002

小海

2022-01-02

15

0

4

1002

小海

2022-01-04

29

2

7

1002

小海

2022-01-07

50

3

9

1003

小辉

2022-04-08

62

0

10

1003

小辉

2022-04-09

62

1

12

1003

小辉

2022-04-11

75

2

14

1003

小辉

2022-04-13

94

2

11

1004

小猛

2022-05-10

12

0

13

1004

小猛

2022-06-12

80

33

 

(2)需求实现

答案一:

select order_id,
       user_id,
       user_name,
       order_date,
       order_amount,
       datediff(order_date, lag(order_date, 1, order_date) over (partition by user_id order by order_date)) diff
from order_info;

答案二:

select
    order_id,
    user_id,
    user_name,
    order_date,
    order_amount,
    nvl(datediff(order_date,last_order_date),0) diff
from
(
    select
        order_id,
        user_id,
        user_name,
        order_date,
        order_amount,
        lag(order_date,1,null) over(partition by user_id order by order_date) last_order_date
    from order_info
)t1

4)查询所有下单记录以及每个用户的每个下单记录所在月份的首/末次下单日期

(1)期望结果

order_id

user_id

user_name

order_date

order_amount

first_date

last_date

1

1001

小元

2022-01-01

10

2022-01-01

2022-01-08

5

1001

小元

2022-01-05

46

2022-01-01

2022-01-08

8

1001

小元

2022-01-08

50

2022-01-01

2022-01-08

3

1001

小元

2022-02-03

23

2022-02-03

2022-02-03

6

1001

小元

2022-04-06

42

2022-04-06

2022-04-06

2

1002

小海

2022-01-02

15

2022-01-02

2022-01-07

4

1002

小海

2022-01-04

29

2022-01-02

2022-01-07

7

1002

小海

2022-01-07

50

2022-01-02

2022-01-07

9

1003

小辉

2022-04-08

62

2022-04-08

2022-04-13

10

1003

小辉

2022-04-09

62

2022-04-08

2022-04-13

12

1003

小辉

2022-04-11

75

2022-04-08

2022-04-13

14

1003

小辉

2022-04-13

94

2022-04-08

2022-04-13

11

1004

小猛

2022-05-10

12

2022-05-10

2022-05-10

13

1004

小猛

2022-06-12

80

2022-06-12

2022-06-12

(2)需求实现

select order_id,
       user_id,
       user_name,
       order_date,
       order_amount,
       first_value(order_date, false)
                   over (partition by user_id,date_format(order_date, 'yyyy-MM') order by order_date rows between unbounded preceding and unbounded following) first_date,
       last_value(order_date, false)
                  over (partition by user_id,date_format(order_date, 'yyyy-MM') order by order_date rows between unbounded preceding and unbounded following)  last_date
from order_info;

 

5)为每个用户的所有下单记录按照订单金额进行排名

(1)期望结果

order_id

user_id

user_name

order_date

order_amount

rk

drk

rn

8

1001

小元

2022-01-08

50

1

1

1

5

1001

小元

2022-01-05

46

2

2

2

6

1001

小元

2022-04-06

42

3

3

3

3

1001

小元

2022-02-03

23

4

4

4

1

1001

小元

2022-01-01

10

5

5

5

7

1002

小海

2022-01-07

50

1

1

1

4

1002

小海

2022-01-04

29

2

2

2

2

1002

小海

2022-01-02

15

3

3

3

14

1003

小辉

2022-04-13

94

1

1

1

12

1003

小辉

2022-04-11

75

2

2

2

9

1003

小辉

2022-04-08

62

3

3

3

10

1003

小辉

2022-04-09

62

3

3

4

13

1004

小猛

2022-06-12

80

1

1

1

11

1004

小猛

2022-05-10

12

2

2

2

(2)需求实现

select order_id,
       user_id,
       user_name,
       order_date,
       order_amount,
       rank() over (partition by user_id order by order_amount desc)       rk,
       dense_rank() over (partition by user_id order by order_amount desc) drk,
       row_number() over (partition by user_id order by order_amount desc) rn
from order_info;

 

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

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

相关文章

多商户商城系统源码-加速度jsudo

为了能顺应时代的改变,很多企业都想要搭建一个类似天猫京东类型的b2b2c商城平台,但苦于没有专业的技术,所以他们都会选择成熟的b2b2c商城系统,但市面上的商城系统如此的多,如何选择呢?下面jsudo小编就来教…

函数式编程相关概念介绍

什么是函数式编程 函数式编程(Functional Programming)也称函数程序设计是一种编程范式,它将电脑运算视为函数运算,并且避免使用程序状态以及可变物件。 在js中,函数是一等公民,函数本身既可以作为其他函数…

spark12-13-14

12. Task线程安全问题 12.1 现象和原理 在一个Executor可以同时运行多个Task,如果多个Task使用同一个共享的单例对象,如果对共享的数据同时进行读写操作,会导致线程不安全的问题,为了避免这个问题,可以加锁&#xff…

操作系统—中断和异常、磁盘调度算法、操作系统其他内容

异常 时常由CPU*执行指令的内部事件引起,比如非法操作码、地址越界、算术溢出等,还有缺页异常、除0异常。同时,他会发送给内核,要求内核处理这些异常。 外中断 狭义上的中断指的就是外中断。由CPU执行指令以外的事件引起&#…

linux高并发网络编程开发(广播-组播-本地套接字)14_tcp udp使用场景,广播通信流程,组播通信流程,本地套接字通信流程,epoll反应堆模型

01 tcp udp使用场景 1.tcp使用场景 对数据安全性要求高的时候  登录数据的传输  文件传输http协议  传输层协议-tcp 2.udp使用场景 效率高-实时性要求比较高  视频聊天  通话有实力的大公司  使用upd  在应用层自定义协议,做数据校验 02 广播通信流程 广播…

LLM 开发实战系列 | 01:API进行在线访问和部署

在本文中,我们将使用Python编程语言来展示如何调用OpenAI的GPT-3.5模型。在开始之前,请确保您已经注册了OpenAI API并获得了访问凭证。 环境准备 下载python 方法1:官网 www.python.org 从最开始的开始,先到Python官网下载一个…

零基础自学:2023年的今天,请谨慎进入网络安全行业

前言 2023年的今天,慎重进入网安行业吧,目前来说信息安全方向的就业对于学历的容忍度比软件开发要大得多,还有很多高中被挖过来的大佬。 理由很简单,目前来说,信息安全的圈子人少,985、211院校很多都才建…

Linux中安装部署docker

目录 什么是docker系统环境要求安装和使用docker 什么是docker Docker是一个开源的容器化平台,用于帮助开发者更轻松地构建、打包、分发和运行应用程序。它基于容器化技术,利用操作系统层级的虚拟化来隔离应用程序和其依赖的环境。通过使用Docker&#…

javaEE进阶 -初识框架

目录 1.为什么要学框架? 框架的优点展示 2、项目的开发 2.1 Servlet 项目的开发 2.2 Spring Boot 项目开发 3 、Spring Boot编写代码 4、 Spring Boot 运行项目 5、验证程序 6、发布项目 主要讲解 四个框架。 1、Spring 2、Spring Boot 3、Spring NVC 4、…

别只盯着Docker了,这十大容器运行时错过后悔

文章目录 一、Docker二、Containerd三、CRI-O四、Firecracker五、gVisor六、Kata七、Lima八、Lxd九、rkt十、runC如何选择适合自己的容器运行时? MCNU云原生,文章首发地,欢迎微信搜索关注,更多干货,第一时间掌握&#…

Apikit 自学日记:数据结构

您可以将API文档中的重复部分提取出来成为数据结构,方便其他文档中复用。当数据结构发生改变时,所有引用了该数据结构的API文档会同步发生改变。 创建数据结构 进入数据结构管理页面,点击 添加数据结构 按钮,输入相关内容并保存…

XXL-JOB任务调度

简介: XXL-JOB 是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。 官网:https://www.xuxueli.com/xxl-job/ 以下业务场景可用任务解决 某电商平台需要每天上午10点,下午3点,晚上8点发…

2023 高质量 Java 面试题集锦:高级 Java 工程师面试八股汇总

人人都想进大厂,当然我也不例外。早在春招的时候我就有向某某某大厂投岗了不少简历,可惜了,疫情期间都是远程面试,加上那时自身也有问题,导致屡投屡败。突然也意识到自己肚子里没啥货,问个啥都是卡卡卡卡&a…

炫技亮点 Websocket集群解决方案汇总

文章目录 问题方案方案一:~~Session共享~~(不可行)方案二:负载均衡器(状态路由)方案三:广播机制(异步方式 - 建议)方案四:路由转发(同步方式&…

【JS经验分享】你真的会写JS吗?满满干货,建议读三遍(2)

大家好,最近准备总结一下JS的经验,分享分享,有不对的欢迎讨论哈~ JS作为前端的基础技能,每一位前端开发都要运用熟练,但你真的会写JS吗?js全称JavaScript,是运行在浏览器上的脚本语言&#xff0…

【高危】Nuxt.js <3.4.3 远程代码执行漏洞(POC公开)

漏洞描述 Nuxt.js(简称 Nuxt)是一个基于 Vue.js 的通用应用框架,用于构建服务端渲染的应用程序(SSR)和静态生成的网站。 Nuxt.js 3.4.3之前版本中的 test-component-wrapper 组件的动态导入函数存在代码注入漏洞,当服务器在开发…

Java集合流式编程

一、简介 1、什么是集合流式编程 集合流式编程(Stream API)是Java 8引入的一个功能强大的特性,它提供了一种更简洁、更高效的方式来操作集合数据。它的设计目标是让开发者能够以一种更声明式的风格来处理集合数据,减少了显式的迭…

Ubuntu部署jmeter与ant

为了整合接口自动化的持续集成工具,我将jmeter与ant都部署在了Jenkins容器中,并配置了build.xml 一、ubuntu部署jdk 1:先下载jdk-8u74-linux-x64.tar.gz,上传到服务器,这里上传文件用到了ubuntu 下的 lrzsz。 ubunt…

WordPress 备份插件 BackUpWordPress

WordPress备份是一件必不可少的事情,毕竟自己辛辛苦苦花了很多时间精力写得博客,经验总结,必须保留传承。WordPress备份可以在发生灾难性情况(比如劫持或意外锁定)下迅速恢复,确保了网站安全。 BackUpWord…

揭示不断增长的预切蔬菜市场:深入研究行业驱动因素和挑战

随着现代社会的快节奏和人们生活压力的增加,越来越多的人选择预制菜作为饮食解决方案,预制菜已经成为餐饮行业的新兴赛道。预制菜的优点包括方便快捷、卫生安全、节省时间、质量可靠,以及丰富的菜品选择和灵活的烹饪和食用方式,满…