hive窗口函数(over)详解
hive窗口函数:
一.函数说明:
OVER()
:指定分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变而变化
CURRENT ROW
:当前行
n PRECEDING
:往前n行数据
n FOLLOWING
:往后n行数据
UNBOUNDED
:起点,UNBOUNDED PRECEDING
表示从前面的起点,UNBOUNDED FOLLOWING
表示到后面的终点
LAG(col,n)
往前第n行数据
LEAD(col,n)
往后第n行数据
NTILE(n)
:把有序分区中的行分发到指定数据的组中,各个组有编号,编号从1开始,对于每一行,NTILE返回此行所属组的编号。注意:n必须为int类型。
二.数据准备:
字段名称:name,orderdate,cost
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
mart,2017-05-10,12
mart,2017-04-11,75
mart,2017-06-12,80
mart,2017-04-13,94
三.需求
(1)查询在2017年4月份购买过的顾客及总人数
(2)查询顾客的购买明细及月购买总额
(3)上述的场景,要将cost按照日期进行累加
(4)查询顾客上次的购买时间
(5)查询前20%时间的订单信息
四.准备
1.创建本地business.txt,导入数据
2.创建hive表并导入数据
create table business(
name string,
orderdate string,
cost int
) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
导入数据
load data local inpath "/business.txt" into table business;
五.按照需求查询数据
(1)查询在2017年4月份购买过的顾客及总人数
1)不使用窗口函数查询:
select name,count(*)
from business
where substring(orderdate,1,7)="2017-04"
group by name;
查询结果:
name | _c1 |
---|---|
jack | 1 |
mart | 4 |
而正确的结果应该是:
name | _c1 |
---|---|
jack | 2 |
mart | 2 |
select name,count(*) over()
from business
where substring(orderdate,1,7)="2017-04"
group by name;
(2)查询顾客的购买明细及月购买总额
月购买总额,要先按照月份进行分区,然后将每一个月的花费进行累加。
select *,sum(cost) over(distribute by month(orderdate)) from business;
此处的distribute by相当于partition by(分区)
结果:
name orderdate cost sum_window_0
jack 2017-01-01 10 205
tony 2017-01-02 15 205
tony 2017-01-07 50 205
jack 2017-01-08 55 205
tony 2017-01-04 29 205
jack 2017-01-05 46 205
jack 2017-02-03 23 23
mart 2017-04-11 75 341
jack 2017-04-06 42 341
mart 2017-04-08 62 341
mart 2017-04-09 68 341
mart 2017-04-13 94 341
mart 2017-05-10 12 12
mart 2017-06-12 80 80
总结:
over函数是针对每一行开了一个窗口,但是可以指定开窗的规则,第一个需求是按照一个人开了一个窗口,第二个需求是按照每个月份开了一个窗口。
(3)上述的场景,要将cost按照日期进行累加
按照日期进行累加,首先要对日期进行排序,然后每一条日期的金额等于之前金额的综合。
select *,sum(cost) over(sort by orderdate rows between UNBOUNDED PRECEDING and CURRENT ROW)
from business;
结果:
name orderdate cost sum_window_0
jack 2017-01-01 10 10
tony 2017-01-02 15 25
tony 2017-01-04 29 54
jack 2017-01-05 46 100
tony 2017-01-07 50 150
jack 2017-01-08 55 205
jack 2017-02-03 23 228
jack 2017-04-06 42 270
mart 2017-04-08 62 332
mart 2017-04-09 68 400
mart 2017-04-11 75 475
mart 2017-04-13 94 569
mart 2017-05-10 12 581
mart 2017-06-12 80 661
每三行一累加:
select *,sum(cost) over(sort by orderdate rows between 1 PRECEDING and 1 FOLLOWING)
from business;
将每个人的花费按照日期进行累加:
select *,sum(cost) over(distribute by name sort by orderdate rows between UNBOUNDED PRECEDING and CURRENT ROW)
from business;
总结:窗口函数(over)中既可以进行排序,也可以进行分区,也可以既排序又分区。而且一个select语句中可以有多个窗口。
(4)查询顾客上次的购买时间
select *,lag(orderdate,1) over(distribute by name sort by orderdate)
from business;
结果:
name orderdate cost lag_window_0
jack 2017-01-01 10 NULL
jack 2017-01-05 46 2017-01-01
jack 2017-01-08 55 2017-01-05
jack 2017-02-03 23 2017-01-08
jack 2017-04-06 42 2017-02-03
tony 2017-01-02 15 NULL
tony 2017-01-04 29 2017-01-02
tony 2017-01-07 50 2017-01-04
mart 2017-04-08 62 NULL
mart 2017-04-09 68 2017-04-08
mart 2017-04-11 75 2017-04-09
mart 2017-04-13 94 2017-04-11
mart 2017-05-10 12 2017-04-13
mart 2017-06-12 80 2017-05-10
总结:这种场景常出现在电商领域,用于求用户的上次购买时间。以及从购买日志信息中查询出用户是否执行完一个完整的购买流程,用户执行完一个完整的购买流程就代表着该用户点击了某件商品之后就付了款。
比如一个电商网站的购买流程页面跳转为(登录页面->商品展示页面->商品详情页面->订单页面->支付页面)那么就要求出整个流程每一步的页面跳转率,从而分析出每一个步骤所出现的问题。
(5)查询前20%时间的订单信息
这里要使用ntile(n),将数据分为指定个数(n)的组。
这里要求前20%时间,所以要先按照时间排序,然后取出前20%的时间,所以要分成5个组,取出第一组。
1.将数据分成5个组:
select *,ntile(5) over(sort by orderdate)
from business;
结果:
name orderdate cost ntile_window_0
jack 2017-01-01 10 1
tony 2017-01-02 15 1
tony 2017-01-04 29 1
jack 2017-01-05 46 2
tony 2017-01-07 50 2
jack 2017-01-08 55 2
jack 2017-02-03 23 3
jack 2017-04-06 42 3
mart 2017-04-08 62 3
mart 2017-04-09 68 4
mart 2017-04-11 75 4
mart 2017-04-13 94 4
mart 2017-05-10 12 5
mart 2017-06-12 80 5
2.查询出前20%的订单信息:
select * from(
select name,orderdate,cost,ntile(5) over(order by orderdate) as sorted
from business
) t
where sorted = 1;
结果:
name orderdate cost sorted
jack 2017-01-01 10 1
tony 2017-01-02 15 1
tony 2017-01-04 29 1
总结:
窗口函数是针对每一行数据来说的,一行数据就对应一个窗口。举个例子来说,select *,sum(cost) from business;
这一个sql语句是错误的,因为select *查询出来是多条数据,而sum(cost)查询出来是一条数据,最终结果匹配不上。
而窗口函数是针对每一行数据开了一个窗口,所以最终结果就能匹配上了。
可以把数据当成游标卡尺上的尺子,那么这个窗口函数就是游标,而分区限制了窗口的移动范围,排序限制了窗口的大小(因为排序时数据是一条一条来的)。
Rank
函数说明:
RANK()
排序相同时会重复,总数不会变,例如某班级成绩排名(有两名同学并列第一),成绩单排名为1134
DENSE_RANK()
排序相同时会重复,总数会减少(成绩单排名为1123)
ROW_NUMBER()
会根据顺序计算(成绩单排名为1234)
rank后面一定要跟着窗口函数
例如求每个学科的前三名:
select name,subject,
rank() over(partition by subject order by score desc),
DENSE_RANK() over(partition by subject order by score desc),
ROW_NUMBER() over(partition by subject order by score desc)
from score;
hive窗口函数(over)详解相关推荐
- Hadoop核心架构HDFS+MapReduce+Hbase+Hive内部机理详解
编者按:HDFS和MapReduce是Hadoop的两大核心,除此之外Hbase.Hive这两个核心工具也随着Hadoop发展变得越来越重要.本文作者张震的博文<Thinking in BigD ...
- hive linux进程数,控制Hive MAP个数详解
控制Hive MAP个数详解 Hive的MAP数或者说MAPREDUCE的MAP数是由谁来决定的呢?inputsplit size,那么对于每一个inputsplit size是如何计算出来的,这是做 ...
- Thinking in BigData(八)大数据Hadoop核心架构HDFS+MapReduce+Hbase+Hive内部机理详解
纯干货:Hadoop核心架构HDFS+MapReduce+Hbase+Hive内部机理详解. 通过这一阶段的调研总结,从内部机理的角度详细分析,HDFS.MapReduce.Hbase.H ...
- 图解大数据 | 海量数据库查询-Hive与HBase详解
Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/cou ...
- [Hive] - Hive参数含义详解
hive中参数分为三类,第一种system环境变量信息,是系统环境变量信息:第二种是env环境变量信息,是当前用户环境变量信息:第三种是hive参数变量信息,是由hive-site.xml文件定义的以 ...
- hive 数据存储格式详解
Hive的三种文件格式:TEXTFILE.SEQUENCEFILE.RCFILE中,TEXTFILE和SEQUENCEFILE的存储格式都是基于行存储的,RCFILE是基于行列混合的思想,先按行把数据 ...
- Hadoop Hive sql语法详解
Hive 是基于Hadoop 构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop 分布式文件系统中的数据,可以将结构 化的数据文件映射为一张数据库表,并提供完整的SQL查 ...
- Hive集成HBase详解
摘要 Hive提供了与HBase的集成,使得能够在HBase表上使用HQL语句进行查询 插入操作以及进行Join和Union等复杂查询 应用场景 1. 将ETL操作的数据存入HBase 2. HBas ...
- Hive JOIN使用详解
Hive是基于Hadoop平台的,它提供了类似SQL一样的查询语言HQL.有了Hive,如果使用过SQL语言,并且不理解Hadoop MapReduce运行原理,也就无法通过编程来实现MR,但是你仍然 ...
- hive之分区表详解
一 新建分区表 语法: PARTITIONEDBY (col type,col type......) 示例: CREATETABLE order ( oid STRING, otime STRING ...
最新文章
- 还不懂Docker?一个故事安排的明明白白!
- o oia ospf 路由优先_动态路由OSPF中注入默认路由,原来都是这么玩的,进去看看...
- 杭电多校(四)2019.7.31--暑假集训
- 有助于项目管理(PM)指导思想
- OSG+VS2010+win7环境搭建---OsgEarth编译
- Unity 代码集锦之图片处理
- Spark _26_Spark On Hive的配置
- Bootstrap 3之美02-Grid简介和应用
- IDEA 中生成 MyBatis 逆向工程实践
- 微信小程序获取用户的头像和昵称
- inline-block和float
- 用一套鼠标键盘控制两台或多台电脑
- zabbix-agent key属性列表
- 不用花钱,让你百度网盘满速下载的神器!简单实用教程
- Java实验-课程设计报告一:个人银行账户管理系统SavingAccountManageSystem-具体文档+源码...
- python注释是什么意思_python中注释的意思是什么
- 腾讯云发送短信验证码
- Python爬虫框架Scrapy入门(三)爬虫实战:爬取长沙链家二手房
- BD新标签页-最值得安装的浏览器插件
- JavaScript弹出模式窗口