原创 | 详解Hive窗口函数及10道实战练习

简介: 原创 | 详解Hive窗口函数及10道实战练习

目录:
一、hive窗口函数语法
----over()窗口函数的语法结构
----常与over()一起使用的分析函数
二、hive窗口函数练习28道题


前言:我们在学习hive窗口函数的时候,一定要先了解窗口函数的结构。而不是直接百度sum() over()、row_number() over()、或者count() over()的用法,如果这样做,永远也掌握不到窗口函数的核心,当然我刚开始的时候也是这样做的,包括去年自己在接触ORACLE分析函数时也是这样搜索。


还好我比较顽强,在HIVE窗口函数问题上折腾了半个月、看了很多文章后才知道over()才是窗口函数,而sum、row_number、count只是与over()搭配的分析函数,当然除了这三个函数还有其他的函数。



一、hive窗口函数语法


在前言中我们已经说了avg()、sum()、max()、min()是分析函数,而over()才是窗口函数,下面我们来看看over()窗口函数的语法结构、及常与over()一起使用的分析函数

1、over()窗口函数的语法结构

2、常与over()一起使用的分析函数

3、窗口函数总结

1、over()窗口函数的语法结构

分析函数 over(partition by 列名 order by 列名 rows between 开始位置 and 结束位置)

over()函数中包括三个函数:包括分区partition by 列名、排序order by 列名、指定窗口范围rows between 开始位置 and 结束位置。我们在使用over()窗口函数时,over()函数中的这三个函数可组合使用也可以不使用。

over()函数中如果不使用这三个函数,窗口大小是针对查询产生的所有数据,如果指定了分区,窗口大小是针对每个分区的数据。


1.1、over()函数中的三个函数讲解


order by

order by是排序的意思,是该窗口中的

A、partition by

partition by可理解为group by 分组。over(partition by 列名)搭配分析函数时,分析函数按照每一组每一组的数据进行计算的。


B、rows between 开始位置 and 结束位置

是指定窗口范围,比如第一行到当前行。而这个范围是随着数据变化的。over(rows between 开始位置 and 结束位置)搭配分析函数时,分析函数按照这个范围进行计算的。

窗口范围说明:

我们常使用的窗口范围是ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW(表示从起点到当前行),常用该窗口来计算累加。


PRECEDING:往前

FOLLOWING:往后
CURRENT ROW:当前行
UNBOUNDED:起点(一般结合PRECEDING,FOLLOWING使用)
UNBOUNDED PRECEDING 表示该窗口最前面的行(起点)
UNBOUNDED FOLLOWING:表示该窗口最后面的行(终点)
比如说:
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW(表示从起点到当前行)
ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING(表示往前2行到往后1行)
ROWS BETWEEN 2 PRECEDING AND 1 CURRENT ROW(表示往前2行到当前行)
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING(表示当前行到终点)

         

         

2、常与over()一起使用的分析函数:


2.1、聚合类

avg()、sum()、max()、min()


2.1、排名类

row_number()按照值排序时产生一个自增编号,不会重复(如:1、2、3、4、5、6)

rank() 按照值排序时产生一个自增编号,值相等时会重复,会产生空位(如:1、2、3、3、3、6)

dense_rank() 按照值排序时产生一个自增编号,值相等时会重复,不会产生空位(如:1、2、3、3、3、4)


2.1、其他类

lag(列名,往前的行数,[行数为null时的默认值,不指定为null]),以计算用户上次购买时间,或者用户下次购买时间。

lead(列名,往后的行数,[行数为null时的默认值,不指定为null])

ntile(n) 把有序分区中的行分发到指定数据的组中,各个组有编号,编号从1开始,对于每一行,ntile返回此行所属的组的编号


3、窗口函数总结:

其实窗口函数逻辑比较绕,我们可以把窗口理解为对表中的数据进行分组,排序等计算。要真正的理解HIVE窗口函数,还是要结合练习题才行。下面我们开始HIVE窗口函数的练习吧!



二、hive窗口函数练习28道题


第一套练习:hive之简单窗口函数 over()


1、使用 over() 函数进行数据统计, 统计每个用户及表中数据的总数

2、求用户明细并统计每天的用户总数
3、计算从第一天到现在的所有 score 大于80分的用户总数
4、计算每个用户到当前日期分数大于80的天数


测试数据

20191020,11111,85
20191020,22222,83
20191020,33333,86
20191021,11111,87
20191021,22222,65
20191021,33333,98
20191022,11111,67
20191022,22222,34
20191022,33333,88
20191023,11111,99
20191023,22222,33

         

建表并导入数据:


         
create table test_window
(logday string,    #logday时间
userid string,
score int)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
#加载数据
load data local inpath '/home/xiaowangzi/hive_test_data/test_window.txt' into table test_window;

我们先看下表中的数据:


select  *  from test_window;


image.png


test_window


1、使用 over() 函数进行数据统计, 统计每个用户及表中数据的总数


select *, count(userid)over() as total  from  test_window;


image.png


这里使用 over() 与 select count(*) 有相同的作用,好处就是,在需要计算总数时不用再进行一次关联。



2、求用户明细并统计每天的用户总数

可以使用 partition by 按日期列对数据进行分区处理,如:over(partition by logday)

select  *,count()over(partition by logday)as day_total from  test_window;

image.png


求每天的用户数可以使用select logday, count(userid) from recommend.test_window group by logday,但是当想要得到 userid 信息时,这种用法的优势就很明显。


3、计算从第一天到现在的所有 score 大于80分的用户总数

此时简单的分区不能满足需求,需要将 order by 和 窗口定义结合使用。


select  *,count()over(order by logday rows between unbounded preceding and current row)as total
from  test_window
where score > 80;

image.png


通过 over() 计算出按日期的累加值。

其实自己刚开始的时候就计算我思路是错了,我就想的是不用累加,直接select *,count()over()as total from test_window where score > 80;这样计算,如果这样计算的话只会显示表中所有大于80的人数,如果我想看20191021或者看20191022的人数看不见。


4、计算每个用户到当前日期分数大于80的天数
select *,
count()over(partition  by userid order by logday rows between unbounded preceding and current row) as total
from test_window
where score > 80  order by logday, userid;

image.png


第二套练习

1、查询在2017年4月份购买过的顾客及总人数
2、查询顾客的购买明细及月购买总额
3、查询顾客的购买明细及到目前为止每个顾客购买总金额
4、查询顾客上次的购买时间----lag()over()偏移量分析函数的运用
5、查询前20%时间的订单信息

         

测试数据

jack,2017-01-01,10
tony,2017-01-02,15
jack,2017-02-03,23
tony,2017-01-04,29
jack,2017-01-05,46
jack,2017-04-06,42
tony,2017-01-07,50
jack,2017-01-08,55
mart,2017-04-08,62
mart,2017-04-09,68
neil,2017-05-10,12
mart,2017-04-11,75
neil,2017-06-12,80
mart,2017-04-13,94

         

建表并加载数据

create table business
(
name string,
orderdate string,
cost int
)ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
#加载数据
load  data local inpath "/home/fengGG/hive_test_data/business.txt" into table business;


查看表数据

select   *  from  business;



image.png


查看表数据


1、查询在2017年4月份购买过的顾客及总人数

分析:按照日期过滤、分组count求总人数(分组为什么不是用group by?自己思考)


select   *,count()over() as total  from  business
where substr(orderdate,1,7) = '2017-04';

image.png


2、查询顾客的购买明细及月购买总额

是计算每月每个用户的消费金额


select
*,
sum(cost) over(partition by name,substr(orderdate,1,7)) total_amount
from
business;

image.png


3、查询顾客的购买明细及到目前为止每个顾客购买总金额

分析:按照顾客分组、日期升序排序、组内每条数据将之前的金额累加


select
*,
sum(cost) over(partition by name order  by  orderdate
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) total_amount
from
business;

image.png



4
、查询顾客上次的购买时间----lag()over()偏移量分析函数的运用

lag()over()偏移量分析函数的运用


select
name,
orderdate,
cost,
lag(orderdate,1) over(partition by name order by orderdate) last_date
from
business;

image.png



5、查询前20%时间的订单信息


         
select  *
from
(select   *,
ntile(5)over(order  by  cost)sortgroup_num from  business)t
where t.sortgroup_num = 1;



image.png



第三套练习

1、每门学科学生成绩排名(是否并列排名、空位排名三种实现)
2、每门学科成绩排名top n的学生


原始数据(学生成绩信息)

name    subject score
孙悟空 语文  87
孙悟空 数学  95
孙悟空 英语  68
大海  语文  94
大海  数学  56
大海  英语  84
宋宋  语文  64
宋宋  数学  86
宋宋  英语  84
婷婷  语文  65
婷婷  数学  85
婷婷  英语  78


建表并加载数据

create table score
(
name string,
subject string,
score int
) row format delimited fields terminated by "\t";
#加载数据
load data local inpath '/home/fengGG/hive_test_data/score.txt' into table score;


查看数据

select  *  from  score;



image.png


1、每门学科学生成绩排名(是否并列排名、空位排名三种实现)


select  *,
row_number()over(partition by subject order by score desc),
rank()over(partition by subject order by score desc),
dense_rank()over(partition by subject order by score desc)
from score

image.png


2、每门学科成绩排名top n的学生


select
*
from
(
select
*,
row_number() over(partition by subject order by score desc) rmp
from score
) t
where t.rmp<=3;

image.png

相关文章
|
4月前
|
SQL HIVE
hive窗口函数应用实例
hive窗口函数应用实例
|
5月前
|
SQL HIVE
Hive 【Hive(七)窗口函数练习】
Hive 【Hive(七)窗口函数练习】
|
5月前
|
SQL 分布式计算 Serverless
Hive【Hive(六)窗口函数】
Hive【Hive(六)窗口函数】
|
5月前
|
SQL 分布式计算 数据挖掘
Hive SQL初级练习(30题)
Hive SQL初级练习(30题)
|
7月前
|
SQL 分布式计算 大数据
黑马程序员-大数据入门到实战-分布式SQL计算 Hive 入门
黑马程序员-大数据入门到实战-分布式SQL计算 Hive 入门
78 0
|
7月前
|
SQL Java 大数据
Hive实战(03)-深入了解Hive JDBC:在大数据世界中实现数据交互
Hive实战(03)-深入了解Hive JDBC:在大数据世界中实现数据交互
239 1
|
5月前
|
SQL 分布式计算 数据库
【大数据技术Spark】Spark SQL操作Dataframe、读写MySQL、Hive数据库实战(附源码)
【大数据技术Spark】Spark SQL操作Dataframe、读写MySQL、Hive数据库实战(附源码)
115 0
|
7月前
|
SQL 存储 大数据
黑马程序员-大数据入门到实战-分布式SQL计算 Hive 语法与概念
黑马程序员-大数据入门到实战-分布式SQL计算 Hive 语法与概念
80 0
|
6天前
|
SQL 数据采集 存储
Hive实战 —— 电商数据分析(全流程详解 真实数据)
关于基于小型数据的Hive数仓构建实战,目的是通过分析某零售企业的门店数据来进行业务洞察。内容涵盖了数据清洗、数据分析和Hive表的创建。项目需求包括客户画像、消费统计、资源利用率、特征人群定位和数据可视化。数据源包括Customer、Transaction、Store和Review四张表,涉及多个维度的聚合和分析,如按性别、国家统计客户、按时间段计算总收入等。项目执行需先下载数据和配置Zeppelin环境,然后通过Hive进行数据清洗、建表和分析。在建表过程中,涉及ODS、DWD、DWT、DWS和DM五层,每层都有其特定的任务和粒度。最后,通过Hive SQL进行各种业务指标的计算和分析。
24 1
Hive实战 —— 电商数据分析(全流程详解 真实数据)
|
2月前
|
SQL HIVE 索引
Hive窗口函数案例总结
Hive窗口函数案例总结