HIVE的Window functions窗口函数【一】

文章目录

  • [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;

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