【Hive】(四)Hive函数——窗口函数


本文转载自: https://blog.csdn.net/weixin_38750084/article/details/82779910
记录为学习笔记

窗口函数

  在SQL中有一类函数叫做聚合函数,例如sum()、avg()、max()等等,这类函数可以将多行数据按照规则聚集为一行,一般来讲聚集后的行数是要少于聚集前的行数的.但是有时我们想要既显示聚集前的数据,又要显示聚集后的数据,这时我们便引入了窗口函数. (新老数据同屏显示,去除聚合,分组的弊端)

窗口函数在所有的后面 比order by前

聚合函数+over()关键字

查询在2015年4月份购买过的顾客及总人数,

select name ,count(*) over() from order where substring(orderdate,1,7)='2015-04';
结果:
name   count(*)购买次数
mart	5
mart	5
mart	5
mart	5
jack	5

去重
select distinct name ,count(*) over() from order where substring(orderdate,1,7)='2015-04';
结果:
mart	2
jack	2

2015-04日每人买的次数

select j.name,j.e from (select name,count(*) over() as e from order where substring(orderdate,1,7)='2015-04') j group by j.name,j.e;

结果:
jack	5
mart	5
每个用户截止到每月为止的最大订单数额和累计到该月的总访问次数

partition by子句

  可以称为查询分区子句,很类似于group by,将数据按照边界值分组,over之前的函数在每一个分组内进行,超出分组,函数重新计算
顾客的购买明细及月购买总额

select name,orderdate,cost,sum(cost) over(partition by month(orderdate))
from order
hive> select name,orderdate,cost,
    > sum(cost) over() as fullagg,
    > sum(cost) over(partition by name) as fullaggbyname,
    > sum(cost) over(partition by name order by orderdate) as fabno
    > from order;
结果:  
jack	2015-01-01	10	661	176	10
jack	2015-01-05	46	661	176	56
jack	2015-01-08	55	661	176	111
jack	2015-02-03	23	661	176	134
jack	2015-04-06	42	661	176	176
mart	2015-04-08	62	661	299	62
mart	2015-04-09	68	661	299	130
mart	2015-04-11	75	661	299	205
mart	2015-04-13	94	661	299	299
neil	2015-05-10	12	661	92	12
neil	2015-06-12	80	661	92	92
tony	2015-01-02	15	661	94	15
tony	2015-01-04	29	661	94	44
tony	2015-01-07	50	661	94	94

order by子句

order by会让输入对方数据 强制排序,因为窗口函数是最后执行的函数 order by默认情况下聚合从起始行到当前行的数据

select name,orderdate,cost,sum(cost) over(partition by month(orderdate) order by orderdate )
from order

window 子句

在partition by分组的情况下更细的划分

  • 只使用partition by,未指定order by 的聚合是 分组内的聚合

  • 使用order by 没有使用window 就是从默认起点到当前行

    多个窗口函数之间并不相互影响

    preceding:往前

    following: 往后

    current row:当前行

    unbounded:起点 unbounded preceding从前面的起点 ubbounded following 到后面的终点

select name,cost,sum(cost) over() as all  #所有行加在一起
sum(cost) over(partition by name) as fz  #按name分组,组内数据全相加
sum(cost) over(partition by name order by orderdate)  #按name分组,组内数据累加,有一行加一行
sum(cost) over(partition by name order by orderdate rows between unbounded preceding and current row) #由起点到当前行
sum(cost) over(partition by name order by orderdate rows between 1 preceding and current row)  #当前行和前面一行聚合
sum(cost) over(partition by name order by orderdate rows between 1 preceding and 1 following) #前一行 当前行 后一行 相加
sum(cost) over(partition by name order by orderdate rows between current row and unbounded following) # 当前行和后面所有行
from order;

序列函数ntile

ntile分片,用于讲数据舒徐切成n片,返回当前切片值

不支持window

应用场景获取顾客的金额前1/3的交易记录

hive> select name,orderdate,cost,ntile(3) over() from order;

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

第一片的数据

hive> select * from (
    > select name,orderdate,cost,ntile(3) over() as pt1 from order
    > ) t where t.pt1 =1;
    
mart	2015-04-13	94	1
neil	2015-06-12	80	1
mart	2015-04-11	75	1
neil	2015-05-10	12	1
mart	2015-04-09	68	1

排序 row_number rank dense_rank

三个排序都会返回排序值

row_number() 有相同的排名,次序不重复 1234

rank() 相同的排名,次序一样,会在次序中留下空位 1224

dense_rank() 相同的额、排名,次序一样,在次序中不会留下空位 1223

hive> select name,orderdate,cost,row_number() over(partition by name order by cost) as rn1,
    > rank() over(partition by name order by cost) as rn2,
    > dense_rank() over(partition by name order by cost) as rn3
    > from order;

jack	2015-01-01	10	1	1	1
jack	2015-02-03	23	2	2	2
jack	2015-03-04	23	3	2	2
jack	2015-04-06	42	4	4	3
jack	2015-01-05	46	5	5	4
jack	2015-01-08	55	6	6	5
mart	2015-04-08	62	1	1	1
mart	2015-04-09	68	2	2	2
mart	2015-04-11	75	3	3	3
mart	2015-04-13	94	4	4	4
neil	2015-05-10	12	1	1	1
neil	2015-06-12	80	2	2	2
tony	2015-01-02	15	1	1	1
tony	2015-01-04	29	2	2	2
tony	2015-01-07	50	3	3	3

LAG和LEAD函数

这两个函数为常用的窗口函数,可以返回上下数据行的数据. 查询上一次
以我们的订单表为例,假如我们想要查看顾客上次的购买时间可以这样去查询

lag(field,n)n表示返回前n行的数据

hive> select name,orderdate,cost,
    > lag(orderdate,5) over(partition by name order by orderdate)
    > from order;

jack	2015-01-01	10	NULL
jack	2015-01-05	46	NULL
jack	2015-01-08	55	NULL
jack	2015-02-03	23	NULL
jack	2015-03-04	23	NULL
jack	2015-04-06	42	2015-01-01
mart	2015-04-08	62	NULL
mart	2015-04-09	68	NULL
mart	2015-04-11	75	NULL
mart	2015-04-13	94	NULL
neil	2015-05-10	12	NULL
neil	2015-06-12	80	NULL
tony	2015-01-02	15	NULL
tony	2015-01-04	29	NULL
tony	2015-01-07	50	NULL
至少消费过6次

first_value和last_value

first_value取分组内排序后,截止到当前行,第一个值
last_value取分组内排序后,截止到当前行,最后一个值

发布了27 篇原创文章 · 获赞 19 · 访问量 1282

猜你喜欢

转载自blog.csdn.net/weixin_42804692/article/details/103586418