Hive窗口函数基础及练习

一、基础知识

我们常见的count()over;sum()over();avg()over()等,其中的count()\sum()\avg()是分析函数,over才是窗口函数。over()函数常与窗口函数()结合使用。

窗口函数的优势在于:在分组统计的同时,可以显示出所有信息,这也弥补了group by“只能显示一条记录”的缺陷。

下面从两方面进行学习,

  • 1、over()窗口函数语法结构
  • 2、常与over()一起使用的分析函数

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

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

其中,partition by 列名类似group by 的功能

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

二、练习

准备工作:

create table test_zyq
(logday string,    
userid string, 
score int)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

#利用shell脚本加载数据
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

注意:创建表的时候不要用“#”加注释。

第一波练习:
1、使用 over() 函数进行数据统计, 统计用户明细及表中数据的总数
?其实这个题目刚开始没有看太明白,
“用户明细”是说查询后显示每个用户的信息,“表中数据总数”是sum所有记录条,
不用窗口函数的写法是分两步:
(1)查表中数据记录总数用count(1)

select count(1) as total from test_zyq;

(2)把每个用户和count结果连接起来

select * from test_zyq,(select count(1) as total from test_zyq) t;

采用窗口函数可以一步到位:

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

注意:此处的 over() 与 select count(1) 有相同的作用,而且over()函数内的部分可以为空。
2、求用户明细并统计每天的用户总数
既然又要有用户明细信息,又要求分组统计,选用窗口函数就可以一步到位。
“统计总数”--分析函数用count(),“每天”是分组的依据

select *,
count(userid)over(partition by logday)
from test_zyq;


3、计算从第一天到当前日期的所有 score 大于80分的用户总数
思路:需要用到rows...between...and...

“总数”--分析函数用cout();“第一天到当前日期” --排序依据(累加)

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

知识点补充:

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(表示当前行到终点)
窗口函数

4、计算每个用户到当前日期分数大于80的天数
"每个用户"--分组依据;;计算天数" ---count(logday) ; "到当前日期" rows...between..and..

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

第二波练习:
数据准备:

create table business
(
name string, 
orderdate string,
cost int
)ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

#数据
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


#加载数据
load  data local inpath "/home/frog005/business.txt" into table business;

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

select *,
count(1) over(partition by month(orderdate))
from business
where month(orderdate)=4;

或者:
筛选条件利用:
‘where substr(orderdate,1,7)='2017-04' ’
2、查询顾客的购买明细及月购买总额

select *,
sum(cost) over(partition by month(orderdate))
from business;

可以在分组依据上加上name,如下:

select *,
sum(cost) over(partition by name,month(orderdate))
from business;

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

select *,
sum(cost) over(partition by name 
rows between unbounded preceding and current row )
from business;

**4、查询顾客上次的购买时间
----lag()over()偏移量分析函数的运用,可用户计算上次购买时间
----lead()over()可计算下一次购买时间
语法:
lead(field, num, defaultvalue) field需要查找的字段,num往后查找的num行的数据,defaultvalue没有符合条件的默认值。

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

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

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

相关知识:

NTILE(n) :
用于将分组数据按照顺序切分成n片,返回当前切片值,如果切片不均匀,默认增加第一个切片的分布。NTILE不支持ROWS BETWEEN,比如 NTILE(2) OVER(PARTITION BY cookieid ORDER BY createtime ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)。

第三波练习:

准备工作:

create table score
(
name string,
subject string, 
score int
) row format delimited fields terminated by "\t";


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

#加载数据
load  data local inpath "/home/frog005/score_zq.txt" into table score;

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

select name,subject,score,
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;

可以看出,在三种排名中,dense_rank()over()的结果比较贴近实际。
2、每门学科成绩排名top n的学生

select 
*
from 
(
select 
*,
dense_rank() over(partition by subject order by score desc) rmp
from score
) t
where t.rmp<=3;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 223,277评论 6 521
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 95,487评论 3 400
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 170,114评论 0 366
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,367评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 69,352评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,919评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,328评论 3 426
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,278评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,808评论 1 321
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,882评论 3 343
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,005评论 1 354
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,672评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,344评论 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,839评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,959评论 1 275
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,481评论 3 379
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,031评论 2 361