定义:窗口 + 函数,在执行函数时,定义一个窗口(函数执行的范围)
CURRENT ROW:当前行
n PRECEDING:往前n行数据
n FOLLOWING:往后n行数据
UNBOUNDED:起点,UNBOUNDED PRECEDING 表示从前面的起点, UNBOUNDED FOLLOWING表示到后面的终点
统计表中字段
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
MAX、MIN、AVG、COUNT、SUM
需求0:查询在2017年4月份购买过的顾客及总人数
select name,count(*) over(rows between UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING)
from business
where year(orderdate)=2017 and month(orderdate)=4
group by name
或
select name,count(*) over()
from business
where year(orderdate)=2017 and month(orderdate)=4
group by name
需求1:查询顾客的购买明细及月购买总额
错误求法:不能求出明细
select name,substring(orderdate,1,7),sum(cost)
from business
group by name,substring(orderdate,1,7)
正确求法:
学习点:
select name,orderdate,cost,sum(cost) over(partition by name,substring(orderdate,1,7) )
from business
需求2:查询顾客每月的购买明细,将cost按照日期进行累加
学习点:
3. over()有order by 没有window子句默认窗口大小是上无边界到当前行
select name,orderdate,cost,sum(cost) over(partition by name,substring(orderdate,1,7)
order by orderdate )
from business
LEAD: LEAD (列名 [,offset] [,default])
取后offset行的数据,如果没取到,用default代替.
要求必须window必须是上下均无边界
LAG: LAG (列名 [,offset] [,default])
取前offset行的数据,如果没取到,用default代替
FIRST_VALUE: FIRST_VALUE(列名,[是否跳过null值])
获取指定列在窗口中的第一个值,可以传入第二个参数为boolean类型,默认为 false,代表是否跳过null值!
LAST_VALUE:LAST_VALUE(列名,[是否跳过null值])
需求3:查看顾客的明细和上次的购买时间
select name,orderdate,cost,lag(orderdate,1,'无数据') over(partition by name
order by orderdate )
from business
需求4:查看顾客的明细和下一笔的购买时间
学习点:
要求窗口是上无边界到下无边界
select name,orderdate,cost,lead(orderdate,1,'无数据') over(partition by name
order by orderdate rows between UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING )
from business
需求5:查询每个顾客每月明细和第一笔订单时间
select name,orderdate,cost,FIRST_VALUE(orderdate,true) over(partition by name,substring(orderdate,1,7)
order by orderdate )
from business
需求6:查询每个顾客每月明细和最后一笔订单时间
学习点:
要求必须window必须是上下均无边界
select name,orderdate,cost,LAST_VALUE(orderdate,true) over(partition by name,substring(orderdate,1,7)
order by orderdate rows between UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING )
from business
需求7:查看顾客的消费明细,以及最近三笔消费总额
方法一:
①当前一笔+之前最近两笔
select name,orderdate,cost,cost
+lag(cost,1,0) over(partition by name order by orderdate )
+lag(cost,2,0) over(partition by name order by orderdate )
from business
或
select name,orderdate,cost,sum(cost) over(partition by name order by orderdate
rows between 2 PRECEDING and current row )
from business
RANK: 允许重复,如果有并列,就跳号!
ROW_NUMBER:连续
DENSE_RANK: 允许重复,如果有并列,不跳号!
CUME_DIST: 当前分数之前的总人数(包括当前分数) / 数据集总人数
PERCENT_RANK: rank-1 / 数据集总人数-1
NTILE(n): 将数据均分到n组中,返回当前数据的组号
需求:查询前20%时间的订单信息// 前x%,就使用cume_dist
select name,orderdate,cost
from
(select name,orderdate,cost, CUME_DIST() over(order by orderdate ) cd
from business) tmp
where cd <=0.2
或
select name,orderdate,cost
from
(select name,orderdate,cost,ntile(5) over(order by orderdate ) n
from business) tmp
where n =1
排名函数练习
// 按照科目进行排名
select name,subject,score, rank() over(partition by subject order by score desc) rk
from score
// 给每个学生的总分进行排名
select name,sum(score) ,rank() over(order by sum(score) desc) rk
from score
group by name
// 只查询每个科目的成绩的前2名
select * from
(select name,subject,score, rank() over(partition by subject order by score desc) rk
from score) tmp
where rk <=2
//查询学生成绩,并显示当前科目最高分
select name,subject,score,FIRST_VALUE(score,true) over(partition by subject order by score desc) maxscore
from score
//查询学生成绩,并显示当前科目最低分
select name,subject,score,FIRST_VALUE(score,true) over(partition by subject order by score ) maxscore
from score
或
select name,subject,score,LAST_VALUE(score,true) over(partition by subject order by score desc
rows between current row and UNBOUNDED FOLLOWING) minscore
from score
year(2017-04-11)
month(2017-04-11)
date_format(‘2019-02-15’,‘yyyy-MM’);
date_add(‘2019-02-15’,-1);
datediff:两个日期相差的天数,前-后
next_day(‘2019-02-12’,‘MO’); 得到下一个周的周一的日期
last_day(‘2019-02-15’); 得到本月的最后一天的日期
lateral view:lateral view explode(category) table_tmp as category_name
explode(列名):将hive一列中复杂的array或者map结构拆分成多行
原表:
《疑犯追踪》 悬疑,动作,科幻,剧情
《Lie to me》 悬疑,警匪,动作,心理,剧情
《战狼2》 战争,动作,灾难
目标数据
《疑犯追踪》 悬疑
《疑犯追踪》 动作
《疑犯追踪》 科幻
《疑犯追踪》 剧情
《Lie to me》 悬疑
《Lie to me》 警匪
《Lie to me》 动作
《Lie to me》 心理
《Lie to me》 剧情
《战狼2》 战争
《战狼2》 动作
《战狼2》 灾难
select
movie,
category_name
from
movie_info lateral view explode(category) table_tmp as category_name;
concat(constellation, “,”, blood_type) :返回n个字符串的拼接结果!如果有一个参数为null,返回null
concat_ws(’|’, collect_set(t1.name)):使用分隔符拼接传入的字符串和字符串数组中的字符串,会跳过分隔符参数后的任何 NULL 和空字符串!
collect_set(col):函数只接受基本数据类型,它的主要作用是将某字段的值进行去重汇总,产生array类型字段
collect_list(col):跟上面函数的区别为不去重
原表:
孙悟空 白羊座 A
大海 射手座 A
宋宋 白羊座 B
猪八戒 白羊座 A
凤姐 射手座 A
目标数据
射手座,A 大海|凤姐
白羊座,A 孙悟空|猪八戒
白羊座,B 宋宋
select
t1.base,
concat_ws('|', collect_set(t1.name)) name
from
(select
name,
concat(constellation, ",", blood_type) base
from
person_info) t1
group by
t1.base;
没有克服不了的困难,只有畏惧的心。 生活之所以耀眼,是因为磨难与辉煌会同时出现。所以,别畏惧暂时的困顿,即使无人鼓掌,也要全情投入,优雅坚持。请相信:不管多险峻的高山,总会给勇敢的人留一条攀登的路。只要你肯迈步,路就会在你脚下延伸。