本文接续上文介绍第三类开窗函数:用于层次查询的开窗函数。共有三种,分别是:ntile()、cume_dist()、percent_rank()。第一个最常用,第二个很少用到,第三个完全没有见过应用场景。所以本文主要介绍ntile()和cume_dist()的语法含义和应用。
函数名 | 描述 |
---|---|
ntile(n) | 将分组数据按照顺序等分成n个切片,返回当前切片的序号。 |
cume_dist() |
返回 (小于等于当前值的行数/分组内总行数) 的比值 |
上述两个函数使用时依旧是后面+开窗函数的固定写法:
over(partition by 列名1,列名2 …… order by 列名3,列名4 …… [desc])
数据准备:
新建test.txt文件,输入如下的三列数据,以空格分隔。第一列是月份,第二列代表商铺名称,第三列代表该商铺该月营业额(万元)。
[root@hadoop ~]# vim test.txt
2019-01 a 1
2019-01 b 2
2019-01 c 3
2019-01 d 4
2019-01 e 5
2019-01 f 6
2019-02 a 2
2019-02 b 4
2019-02 c 6
2019-02 d 8
2019-02 e 10
2019-02 f 12
在hive中新建表temp_test11,将test文件中的数据插入,查看数据。
CREATE TABLE temp_test11 (
month STRING comment '月份'
,shop STRING comment '商铺名称'
,money INT comment '营业额(万元)'
) row format delimited fields terminated BY ' ';
load data local inpath '/root/test.txt' into table temp_test11;
select * from temp_test11;
temp_test11.month temp_test11.shop temp_test11.money
2019-01 a 1
2019-01 b 2
2019-01 c 3
2019-01 d 4
2019-01 e 5
2019-01 f 6
2019-02 a 2
2019-02 b 4
2019-02 c 6
2019-02 d 8
2019-02 e 10
2019-02 f 12
ntile(n)用于将分组数据按照顺序等分成n个切片,返回当前切片的序号。如果切片不均匀,默认增加第几个切片的分布。
1.按月份分区按营业额从小到大排序,将数据等分成2份,rk=1的是每个分区内前50%营业额的数据,rk=2的是为每个分区内后50%营业额的数据。
SELECT month
,shop
,MONEY
,ntile(2)OVER (PARTITION BY month ORDER BY money) AS rk
FROM temp_test11
order by month
,shop;
结果:
month shop money rk
2019-01 a 1 1
2019-01 b 2 1
2019-01 c 3 1
2019-01 d 4 2
2019-01 e 5 2
2019-01 f 6 2
2019-02 a 2 1
2019-02 b 4 1
2019-02 c 6 1
2019-02 d 8 2
2019-02 e 10 2
2019-02 f 12 2
2.按月份分区按营业额从大到小排序,将数据等分成3份,rk=1的是每个分区内前1/3营业额的数据,rk=2的是为每个分区内中间1/3营业额的数据,rk=3的是为每个分区内后1/3营业额的数据。
SELECT month
,shop
,MONEY
,ntile(3)OVER (PARTITION BY month ORDER BY money desc) AS rk
FROM temp_test11
order by month
,shop;
结果:
month shop money rk
2019-01 a 1 3
2019-01 b 2 3
2019-01 c 3 2
2019-01 d 4 2
2019-01 e 5 1
2019-01 f 6 1
2019-02 a 2 3
2019-02 b 4 3
2019-02 c 6 2
2019-02 d 8 2
2019-02 e 10 1
2019-02 f 12 1
3.按月份分区按营业额从小到大排序,将数据分成4份,但是由于每个分组内只有6行数据,无法等分成4组,所以前两组分别多分1行数据。
SELECT month
,shop
,MONEY
,ntile(4)OVER (PARTITION BY month ORDER BY money) AS rk
FROM temp_test11
order by month
,shop;
结果:
month shop money rk
2019-01 a 1 1
2019-01 b 2 1
2019-01 c 3 2
2019-01 d 4 2
2019-01 e 5 3
2019-01 f 6 4
2019-02 a 2 1
2019-02 b 4 1
2019-02 c 6 2
2019-02 d 8 2
2019-02 e 10 3
2019-02 f 12 4
ntile(n)函数在数据分析中应用很广,常见场景有以下几种:
cume_dist()用于返回 (小于等于当前值的行数/分组内总行数) 的比值,应用场景较少,可以不掌握。
举例:
按月份分区按营业额从小到大排序,计算出每个月小于等于每个营业额的商铺数量占该月的总商铺数量的比例
SELECT month
,shop
,MONEY
,cume_dist() OVER (PARTITION BY month ORDER BY money) AS rk
FROM temp_test11
where shop not in ('e','f')
结果:
month shop money rk
2019-01 a 1 0.25
2019-01 b 2 0.5
2019-01 c 3 0.75
2019-01 d 4 1.0
2019-02 a 2 0.25
2019-02 b 4 0.5
2019-02 c 6 0.75
2019-02 d 8 1.0
能看到这里的同学,就右上角点个赞吧,3Q~