文章目录
- [1. 窗口函数概述](#1. 窗口函数概述)
- [2. 窗口函数语法](#2. 窗口函数语法)
- [3. 案例:网站用户页面浏览次数分析](#3. 案例:网站用户页面浏览次数分析)
-
- [3.1 窗口聚合函数](#3.1 窗口聚合函数)
1. 窗口函数概述
窗口函数(Window functions)是一种SQL函数,非常适合于数据分析,因此也叫做OLAP函数
其最大特点是:输入值是从SELECT语句的结果集中的一行或多行的"窗口"中获取的。你也可以理解为窗口有大有小(行有多有少)。
通过OVER子句,窗口函数与其他SQL函数有所区别。如果函数具有OVER子句,则它是窗口函数。如果它缺少OVER子句,则它是一个普通的聚合函数。
窗口函数可以简单地解释为类似于聚合函数的计算函数,但是通过GROUP BY子句组合的常规聚合会隐藏正在聚合的各个行,最终输出一行,窗口函数聚合后还可以访问当中的各个行,并且可以将这些行中的某些属性添加到结果集中。
为了更加直观感受窗口函数,我们通过sum聚合函数进行普通常规聚合和窗口聚合,一看效果。
- 数据准备
sql
create external table day05_hive.employee(
id int,
name string comment '角色',
deg string comment '角色',
salary int comment '售价',
dept string comment '部门'
);
describe formatted employee;
insert into employee
values (1201, 'zhangsan', 'manager', 50000, 'TP'),
(1202, 'lisi', 'cto', 50000, 'TP'),
(1203, 'wangwu', 'dev', 30000, 'AC'),
(1204, 'xuliu', 'dev', 30000, 'AC'),
(1206, 'gaoqi', 'admin', 20000, 'TP');
select * from employee;
- 效果演示
- sum+group by普通常规聚合操作
sql
select dept, sum(salary) as total from employee group by dept;

- sum+窗口函数聚合操作
sql
select id,name,deg,salary,dept, sum(salary) over(partition by dept) as total from employee;

2. 窗口函数语法
sql
Function(arg1,..., argn) OVER ([PARTITION BY <...>] [ORDER BY <....>] [<window_expression>])
其中Function(arg1,..., argn) 可以是下面分类中的任意一个
--聚合函数:比如sum max avg等
--排序函数:比如rank row_number等
--分析函数:比如lead lag first_value等
OVER [PARTITION BY <...>] 类似于group by 用于指定分组 每个分组你可以把它叫做窗口,如果没有PARTITION BY 那么整张表的所有行就是一组ORDER BY \<...\>\] 用于指定每个分组内的数据排序规则 支持ASC、DESC \[\
\] 用于指定每个窗口中 操作的数据范围 默认是窗口中所有行
3. 案例:网站用户页面浏览次数分析
在网站访问中,经常使用cookie来标识不同的用户身份,通过cookie可以追踪不同用户的页面访问情况,有下面两份数据:
字段含义:cookieid 、访问时间、pv数(页面浏览数)

字段含义:cookieid、访问时间、访问页面url
在Hive中创建两张表,把数据加载进去用于窗口分析。
---建表并且加载数据
sql
create table website_pv_info(
cookieid string,
createtime string, --day
pv int
) row format delimited
fields terminated by ',';
create table website_url_info (
cookieid string,
createtime string, --访问时间
url string --访问页面
) row format delimited
fields terminated by ',';
load data local inpath '/root/hivedata/website_pv_info.txt' into table website_pv_info;
load data local inpath '/root/hivedata/website_url_info.txt' into table website_url_info;
select * from website_pv_info;
select * from website_url_info;
3.1 窗口聚合函数
从Hive v2.2.0开始,支持DISTINCT与窗口函数中的聚合函数一起使用。
这里以sum()函数为例,其他聚合函数使用类似。
sql
-----窗口聚合函数的使用-----------
--1、求出每个用户总pv数 sum+group by普通常规聚合操作
select cookieid,sum(pv) as total_pv from website_pv_info group by cookieid;
--2、sum+窗口函数 总共有四种用法 注意是整体聚合 还是累积聚合
--sum(...) over( )对表所有行求和
--sum(...) over( order by ... ) 连续累积求和
--sum(...) over( partition by... ) 同组内所有行求和
--sum(...) over( partition by... order by ... ) 在每个分组内,连续累积求和
--需求:求出网站总的pv数 所有用户所有访问加起来
--sum(...) over( )对表所有行求和
select cookieid,createtime,pv,
sum(pv) over() as total_pv
from website_pv_info;
--需求:求出每个用户总pv数
--sum(...) over( partition by... ),同组内所行求和
select cookieid,createtime,pv,
sum(pv) over(partition by cookieid) as total_pv
from website_pv_info;
--需求:求出每个用户截止到当天,累积的总pv数
--sum(...) over( partition by... order by ... ),在每个分组内,连续累积求和
select cookieid,createtime,pv,
sum(pv) over(partition by cookieid order by createtime) as current_total_pv
from website_pv_info;
下面主要运行结果进行截图,
需求:求出网站总的pv数 所有用户所有访问加起来
需求:求出每个用户总pv数
需求:求出每个用户截止到当天,累积的总pv数
这里你可能有疑问,为何加了orderby就能实现累计呢,它的意思不是排序么,这里就需要注意了,在窗口聚合函数中ORDER BY不仅对窗口内的数据进行排序,还会定义聚合范围(即窗口帧)。默认情况下,加ORDER BY会设定范围为从分区开始到当前行(ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),导致计算结果为累计值。
实际上的SQL为以下内容
sql
select cookieid,
createtime,
pv,
sum(pv)
over (partition by cookieid order by createtime rows between unbounded preceding and current row )
as current_total_pv
from website_pv_info;

如果有帮助到你,请点赞收藏