Hive 常用的窗口函数【高频重点】(上)

简介: Hive 常用的窗口函数【高频重点】

1、Hive 常用的窗口函数:

按照功能划分:

● 序号函数: rank () /dense_rank () /row_number ()

分布函数:percent_rank () /cume_dist ()

前后函数:lag () /lead ()

头尾函数:first_val () /last_val ()

聚合函数 + 窗⼝函数联合:

                    ○ 求和 sum () over ()

                    ○ 求最⼤ / ⼩ max ()/min () over ()

                    ○ 求平均 avg () over ()

其他函数:nth_value () /nfile ()

 

如上,窗⼝函数的⽤法多种多样,不仅有专⻔的的窗⼝函数,还可以与聚合函数配合使⽤。他们都要跟窗口子句 Over()一起使用才行,放在 over()函数的前面。

 

2、各个窗口函数的含义:

RANK() :返回一个数字,该数字表示在窗口内当前行的排名,排序相同时会重复,最后显示的总数不会变。

即如果有两个用户的值相同,则并列第一,那么下一个排名应该是第三名。

如:1-2-3-3-5-6

 

DENSE_RANK() :返回一个数字,该数字表示在窗口内当前行的排名,排序相同时会重复,下一个排名将被跳过,最后显示的总数会减少。

即如果有两个用户的值相同,则并列第一,那么下一个排名应该是第二名。

如:1-2-3-3-4-5

 

ROW_NUMBER() :返回一个数字,该数字表示在窗口内当前行的排名,会根据顺序计算,每行都有一个唯一的行号,从 1 开始,依次递增。如:1-2-3-4-5

 

percent_rank():返回所在窗口中当前行的百分比排名

 

cume_dist(): 如果按升序排列,则统计:⼩于等于当前值的⾏数 / 总⾏数。

                   如果是降序排列,则统计:⼤于等于当前值的⾏数 / 总⾏数。

 

LAG(col,n):返回所在窗口中当前行前面第 n 行的值。

 

LEAD(col,n):返回指定窗口中当前行后面第 n 行的值。

 

first_value():返回所在窗口中第一行的值。

 

last_value():返回所在窗口中最后一行的值。

 

max()、min()、sum()、avg()、count():常用的聚合函数。

 

NTILE(n):将窗口划分为 n 个桶,并返回当前行所在桶的编号。可用于 where 条件中,传入桶的编号返回桶内的数据。

 

特别说明:上述的这些函数必须跟着 over()一起使用,不能单独使用。

 

 

3、开窗函数 over ( ) 中加 order by 和 不加 order by 的区别:

如果使⽤环境为 hive,over ( ) 开窗函数前分排序函数和聚合函数两种。

当为排序函数,如 row_number (),rank () 等时,over 中的 order by 只起到窗⼝内排序作⽤。

当为聚合函数,如 max,min,count 等时,over 中的 order by 不仅起到窗⼝内排序,还起到窗⼝内从当前⾏到之前所有⾏的聚合(多了⼀个范围)。

 

 

4、窗⼝函数与普通聚合函数的区别:

(1)聚合函数是将多条记录聚合为⼀条;窗⼝函数是每条记录都会执⾏,有⼏条记录执⾏完还是⼏条。

(2)窗⼝函数兼具 GROUP BY ⼦句的分组功能以及 ORDER BY ⼦句的排序功能。但是,PARTITION BY ⼦句并不具备 GROUP BY ⼦句的汇总功能。

 

5、 OVER ( )(开窗函数)用于执行基于窗口的聚合计算的函数,它把数据分为不同的窗口,并在每个窗口上执行聚合计算。

 

Over()函数的语法如下:

OVER (
    [ PARTITION BY partition_expression, ... ]
    [ ORDER BY sort_expression [ ASC | DESC ], ... ]
    [ ROWS/RANGE BETWEEN frame_start AND frame_end ]
  )

在 over()函数内可以通过 partition by 指定分区,也可以通过 order by 指定排序方式,同时还可以根据 rows/range   between  and 框架子句指定窗口的大小和位置;这三个部分是可选的参数。

指定窗口大小和位置的参数如下:

CURRENT ROW:当前行

n PRECEDING:往前 n 行数据

n FOLLOWING:往后 n 行数据

UNBOUNDED:起点,

UNBOUNDED PRECEDING 表示从前面的起点,

UNBOUNDED FOLLOWING 表示到后面的终点

示例:
SELECT col1, col2, SUM(col3) OVER (PARTITION BY col1 ORDER BY col2 ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) as sum_col3
FROM table;

 

6、案例展示:

1)数据准备:nameorderdatecost

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

 

2)创建 hive 表并导入数据

create table business(

name string,

orderdate string,

cost int

) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

load data local inpath "/opt/module/data/business.txt" into table

business;

 

3)按需求查询数据

(3.1)查询顾客及总人数

select

       name,

       count(*) over ()

from business;

结果显示:

说明:如果没有 over()函数的话,那么查询出来的 count(*)只有一行数据,name 字段与 count(*)字段匹配不上,所以会出错。而用了 over()函数之后,count(*)字段的数据会与每一个 name 字段的数据相匹配,因为 over()函数将整张表作为了一个窗口。

 

(3.2)查询在 2017 4 月份购买过的顾客及总人数

select

       name,

       count(*) over ()

       from business

       where substring(orderdate,1,7) = '2017-04'

group by name;

结果显示:

注明:这里用 over(),over()中没有写其他功能,那它会将整个表作为一个整体计算并对应每行数据显示出来。

substring(字符串,起始位置,截取多少位):substring()函数用于截取字符串,字符串位置从 0 开始计算,注意第三个参数代表截取多少位,,而不是截取到字符串哪个位置,可以不填写表示截取到字符串最后一位。

 

(3.3)查询顾客的购买明细及月购买总额

select

       name,

       orderdate,

       cost,

       sum(cost) over(partition by name, month(orderdate))

from business;

结果显示:

说明:sum(cost) over(partition by name, month(orderdate)) 表示,按照相同人名、同一月份进行开窗,数据在各自的窗口进行处理,sum(cost)计算的是各个区内的数据,不是整个表的数据。也就是对相同人名、同一月份进行开窗。

 

(3.4)将每个顾客的 cost 按照日期进行累加

select name,orderdate,cost,

       sum (cost) over () as sample1,-- 所有行相加

       sum (cost) over (partition by name) as sample2,-- 按 name 分组,组内数据相加

       sum (cost) over (partition by name order by orderdate) as sample3,-- 按 name

分组,组内数据累加

       sum(cost) over(partition by name order by orderdate rows between

       UNBOUNDED PRECEDING and current row ) as sample4 ,-- 和 sample3 一样 , 由起点到

当前行的聚合

       sum(cost) over(partition by name order by orderdate rows between 1

       PRECEDING and current row) as sample5, -- 当前行和前面一行做聚合

       sum(cost) over(partition by name order by orderdate rows between 1

       PRECEDING AND 1 FOLLOWING ) as sample6,-- 当前行和前边一行及后面一行

       sum(cost) over(partition by name order by orderdate rows between current

       row and UNBOUNDED FOLLOWING ) as sample7 -- 当前行及后面所有行

from business;

注意:rows 必须跟在 order by 子句之后,对排序的结果进行限制,使用固定的行数来限制分区中的数据行数量

 

(3.5)查看顾客上次的购买时间

select

       name,

       orderdate,

       cost,

       lag(orderdate,1,'1900-01-01') over(partition by name order by orderdate ) as time1,

       lag(orderdate,2) over (partition by name order by orderdate) as time2

from business;

结果显示:

说明:lag(col,n,default_val)函数要用在 over()前面。表示往前 n 行取数据,其中前面没有行的,则用 default_val 代替。LEAD(col,n,default_val)函数用法和 LAG(col,n,default_val)函数一样,表示往后 n 行取数据。

相关文章
|
7月前
|
SQL HIVE
hive窗口函数应用实例
hive窗口函数应用实例
173 3
|
7月前
|
SQL HIVE
Hive 【Hive(七)窗口函数练习】
Hive 【Hive(七)窗口函数练习】
|
7月前
|
SQL 分布式计算 Serverless
Hive【Hive(六)窗口函数】
Hive【Hive(六)窗口函数】
|
SQL 大数据 开发工具
大数据Hive窗口函数应用实例 2
大数据Hive窗口函数应用实例
165 0
|
SQL 大数据 开发工具
大数据Hive窗口函数应用实例 1
大数据Hive窗口函数应用实例
98 0
|
3月前
|
SQL JavaScript 前端开发
Hive学习-lateral view 、explode、reflect和窗口函数
Hive学习-lateral view 、explode、reflect和窗口函数
53 4
|
7月前
|
SQL HIVE 索引
Hive窗口函数案例总结
Hive窗口函数案例总结
|
7月前
|
SQL
bigdata-23-Hive窗口函数
bigdata-23-Hive窗口函数
51 0
Hive学习---4、函数(单行函数、高级聚合函数、炸裂函数、窗口函数)(二)
Hive学习---4、函数(单行函数、高级聚合函数、炸裂函数、窗口函数)(二)
|
SQL HIVE
Hive 常用的窗口函数【高频重点】(下)
Hive 常用的窗口函数【高频重点】(下)
83 0