Hive零基础从入门到实战 进阶篇(十五) HiveQL:开窗函数(累计统计)

目录

 

前言

1. 什么是开窗函数

2. 开窗函数语法

3. 开窗函数分类

4. 组内累计统计开窗函数

4.1 累计求和 sum(xx) over

4.2 累计求平均值 avg(xx) over

4.3 累计求最大值 max(xx) over

4.4 累计求最小值 min(xx) over


 

前言

从本文开始介绍Hive中开窗函数系列。这类函数叫法很多,包括分析函数、窗口函数、开窗函数、分析窗口函数,其实说的都是一类函数,本系列博客后续均采用开窗函数的命名方式。

 

1. 什么是开窗函数

这里直接上百度百科的定义:

开窗函数用于为行定义一个窗口(这里的窗口是指运算将要操作的行的集合),它对一组值进行操作,不需要使用GROUP BY子句对数据进行分组,能够在同一行中同时返回基础行的列和聚合列。

 

2. 开窗函数语法

开窗函数的语法为:

over(partition by 列名1,列名2 …… order by 列名3,列名4 …… [desc])

括号中的两个关键词partition by 和order by 可以只出现一个。

partition by 和order by 后面的列名可以根据需求设定任意数量个列名。

order by后面可以选择是否跟desc,加上为倒序排序(从大到小),不加则默认为从小到大排序。

over() 前面是一个函数。

 

3. 开窗函数分类

在Hive中开窗函数按功能主要分为以下四类:

  1. 组内累计统计
  2. 组内排序
  3. 组内层次查询
  4. 组内偏移关联

 

4. 组内累计统计开窗函数

本文主要介绍第一类开窗函数,即用于组内累计统计的开窗函数:sum、avg、min、max。

数据准备:

新建test.txt文件,输入如下的三列数据,以空格分隔。第一列是月份,第二列代表商铺名称,第三列代表该商铺该月营业额(万元)。

[root@hadoop ~]# vim test.txt 

2019-01 a 10
2019-02 a 20
2019-03 a 30
2019-01 b 10
2019-02 b 20
2019-03 b 30

在hive中新建表temp_test9,将test文件中的数据插入,查看数据。

CREATE TABLE temp_test9 (
      month STRING comment '月份'
      ,shop STRING comment '商铺名称'
      ,money STRING comment '营业额(万元)'
      ) row format delimited fields terminated BY ' ';
 
 
load data local inpath '/root/test.txt' into table temp_test9;
 
select * from temp_test9;
 
temp_test9.month	temp_test9.shop	temp_test9.money
2019-01	a	10
2019-02	a	20
2019-03	a	30
2019-01	b	10
2019-02	b	20
2019-03	b	30

4.1 累计求和 sum(xx) over

求商店a每个月从1月累计到该月的总营业额,即:

  • 1月的数据是1月的营业额
  • 2月的数据是1月+2月的营业额
  • 3月的数据是1月+2月+3月的营业额
SELECT month
      ,SUM(MONEY) OVER (
            ORDER BY month  --按照月份进行排序,然后默认从起点行到当前行做累计求和
            ) AS money_leiji
FROM temp_test9
WHERE shop = 'a'; --开窗函数不用写group by

结果:
month	money_leiji
2019-01	10.0
2019-02	30.0
2019-03	60.0

同时求出商店a、b每个月从1月累计到该月的总营业额

SELECT shop
      ,month
      ,SUM(MONEY) OVER (
            PARTITION BY shop ORDER BY month --先按照shop进行分组,然后每个组内再按照月份进行排序,最后默认从起点行到当前行做累计求和
            ) AS money_leiji
FROM temp_test9;


结果:
shop	month	money_leiji
a	2019-01	10.0
a	2019-02	30.0
a	2019-03	60.0
b	2019-01	10.0
b	2019-02	30.0
b	2019-03	60.0

只分组求和也不会报错,但这样没什么意义,不如直接使用group by。

SELECT shop
      ,month
      ,SUM(MONEY) OVER (PARTITION BY shop) AS money_leiji
FROM temp_test9;

shop	month	money_leiji
a	2019-03	60.0
a	2019-02	60.0
a	2019-01	60.0
b	2019-03	60.0
b	2019-02	60.0
b	2019-01	60.0


不写month也会统计出来3个组内求和
SELECT shop
      ,SUM(money) OVER (
            PARTITION BY shop
            ) AS money_leiji
FROM temp_test9;

shop	money_leiji
a	60.0
a	60.0
a	60.0
b	60.0
b	60.0
b	60.0

除了上面常用的累计求和方式之外,Hive还允许自定义累计方式。默认的累计方式是按起点行到当前行做累计,自定义累计方式主要有以下4种:

  1. 当前行+往前几行
  2. 当前行+往后几行
  3. 当前行+往前几行+往后几行
  4. 当前行+往后所有行

这几种自定义的累计方式应用场景很少,可以不掌握,这里只介绍一下语法:

  • 当前行+往前几行
1 PRECEDING指往前1行,这里可以根据需求任意指定数值

OVER (PARTITION BY 列名1 ORDER BY 列名2 ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)
  • 当前行+往后几行
1 FOLLOWING指往后1行,这个值可以根据需求指定任意数值

OVER (PARTITION BY 列名1 ORDER BY 列名2 ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING)
  • 当前行+往前几行+往后几行
1 PRECEDING指往前1行,1 FOLLOWING指往后1行,这两个值均可以根据需求指定任意数值

OVER (PARTITION BY 列名1 ORDER BY 列名2 ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
  • 当前行+往后所有行
OVER (PARTITION BY 列名1 ORDER BY 列名2 ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)

 

4.2 累计求平均值 avg(xx) over

其他的开窗函数和求和的累计逻辑都是相同的。

举例:

同时求出商店a、b每个月从1月累计到该月的平均营业额

SELECT shop
      ,month
      ,AVG(MONEY) OVER (
            PARTITION BY shop ORDER BY month --先按照shop进行分组,然后每个组内再按照月份进行排序,最后默认从起点行到当前行做累计求均值
            ) AS money_leiji
FROM temp_test9;


结果:
shop	month	money_leiji
a	2019-01	10.0
a	2019-02	15.0
a	2019-03	20.0
b	2019-01	10.0
b	2019-02	15.0
b	2019-03	20.0

 

4.3 累计求最大值 max(xx) over

举例:

同时求出商店a、b每个月从1月累计到该月的营业额最大值

SELECT shop
      ,month
      ,MAX(MONEY) OVER (
            PARTITION BY shop ORDER BY month --先按照shop进行分组,然后每个组内再按照月份进行排序,最后默认从起点行到当前行做累计求最大值
            ) AS money_leiji_max
FROM temp_test9;


结果:
shop	month	money_leiji_max
a	2019-01	10
a	2019-02	20
a	2019-03	30
b	2019-01	10
b	2019-02	20
b	2019-03	30

 

4.4 累计求最小值 min(xx) over

举例:

同时求出商店a、b每个月从1月累计到该月的营业额最小值

SELECT shop
      ,month
      ,MIN(MONEY) OVER (
            PARTITION BY shop ORDER BY month --先按照shop进行分组,然后每个组内再按照月份进行排序,最后默认从起点行到当前行做累计求最小值
            ) AS money_leiji_min
FROM temp_test9;


结果:
shop	month	money_leiji_min
a	2019-01	10
a	2019-02	10
a	2019-03	10
b	2019-01	10
b	2019-02	10
b	2019-03	10

 


能看到这里的同学,就右上角点个赞吧,3Q~

你可能感兴趣的:(Hive零基础从入门到实战 进阶篇(十五) HiveQL:开窗函数(累计统计))