Hive分析窗体函数之NTILE,ROW_NUMBER,RANK和DENSE_RANK
继续介绍几个序列函数:
NTILE。ROW_NUMBER,RANK和DENSE_RANK
环境信息:
Hive版本号为apache-hive-0.14.0-bin
Hadoop版本号为hadoop-2.6.0
Tez版本号为tez-0.7.0
数据:
P088888888888,2016-02-10,1
P088888888888,2016-02-11,3
P088888888888,2016-02-12,1
P088888888888,2016-02-13,9
P088888888888,2016-02-14,3
P088888888888,2016-02-15,12
P088888888888,2016-02-16,3
P066666666666,2016-02-10,6
P066666666666,2016-02-11,2
P066666666666,2016-02-12,1
P066666666666,2016-02-13,9
P066666666666,2016-02-14,2
P066666666666,2016-02-15,20
P066666666666,2016-02-16,2
导入数据到Hive表中:
load data local inpath '/home/hadoop/testhivedata/windows_func.txt' overwrite into table windows_func;
NTILE
NTILE(n)。用于将分组数据依照顺序切分成n片。返回当前切片值
NTILE不支持ROWS BETWEEN,比方 NTILE(2) OVER(PARTITION BY polno ORDER BY createtime ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)
假设切片不均匀。默认添加第一个切片的分布。
SELECT
polno,
createtime,
pnum,
NTILE(2) OVER(PARTITION BY polno ORDER BY createtime) AS rn1, --分组内将数据分成2片
NTILE(3) OVER(PARTITION BY polno ORDER BY createtime) AS rn2, --分组内将数据分成3片
NTILE(4) OVER(ORDER BY createtime) AS rn3 --将全部数据分成4片
FROM windows_func ORDER BY polno,createtime;
结果:
polno createtime pnum rn1 rn2 rn3
P066666666666 2016-02-10 6 1 1 1
P066666666666 2016-02-11 2 1 1 1
P066666666666 2016-02-12 1 1 1 2
P066666666666 2016-02-13 9 1 2 2
P066666666666 2016-02-14 2 2 2 3
P066666666666 2016-02-15 20 2 3 3
P066666666666 2016-02-16 2 2 3 4
P088888888888 2016-02-10 1 1 1 1
P088888888888 2016-02-11 3 1 1 1
P088888888888 2016-02-12 1 1 1 2
P088888888888 2016-02-13 9 1 2 2
P088888888888 2016-02-14 3 2 2 3
P088888888888 2016-02-15 12 2 3 4
P088888888888 2016-02-16 3 2 3 4
--比方,pnum数最多的前1/3的天
--rn = 1 的记录,就是我们想要的结果
SELECT polno,
createtime,
pnum,
NTILE(3) OVER(PARTITION BY polno ORDER BY pnum DESC) AS rn
FROM windows_func;
结果:
polno createtime pnum rn
P066666666666 2016-02-15 20 1
P066666666666 2016-02-13 9 1
P066666666666 2016-02-10 6 1
P066666666666 2016-02-16 2 2
P066666666666 2016-02-11 2 2
P066666666666 2016-02-14 2 3
P066666666666 2016-02-12 1 3
P088888888888 2016-02-15 12 1
P088888888888 2016-02-13 9 1
P088888888888 2016-02-16 3 1
P088888888888 2016-02-11 3 2
P088888888888 2016-02-14 3 2
P088888888888 2016-02-12 1 3
P088888888888 2016-02-10 1 3
ROW_NUMBER
ROW_NUMBER() –从1開始,依照顺序,生成分组内记录的序列
–比方,依照pnum降序排列。生成分组内每天的pnum名次
ROW_NUMBER() 的应用场景许多。再比方,获取分组内排序第一的记录等等。
SELECT polno,
createtime,
pnum,
ROW_NUMBER() OVER(PARTITION BY polno ORDER BY pnum desc) AS rn
FROM windows_func;
结果:
polno createtime pnum rn
P066666666666 2016-02-15 20 1
P066666666666 2016-02-13 9 2
P066666666666 2016-02-10 6 3
P066666666666 2016-02-16 2 4
P066666666666 2016-02-11 2 5
P066666666666 2016-02-14 2 6
P066666666666 2016-02-12 1 7
P088888888888 2016-02-15 12 1
P088888888888 2016-02-13 9 2
P088888888888 2016-02-16 3 3
P088888888888 2016-02-11 3 4
P088888888888 2016-02-14 3 5
P088888888888 2016-02-12 1 6
P088888888888 2016-02-10 1 7
RANK 和 DENSE_RANK
—RANK() 生成数据项在分组中的排名,排名相等会在名次中留下空位
—DENSE_RANK() 生成数据项在分组中的排名,排名相等会在名次中不会留下空位
SELECT polno,
createtime,
pnum,
RANK() OVER(PARTITION BY polno ORDER BY pnum desc) AS rn1,
DENSE_RANK() OVER(PARTITION BY polno ORDER BY pnum desc) AS rn2,
ROW_NUMBER() OVER(PARTITION BY polno ORDER BY pnum DESC) AS rn3
FROM windows_func WHERE polno ='P066666666666';
结果:
polno createtime pnum rn1 rn2 rn3
P066666666666 2016-02-15 20 1 1 1
P066666666666 2016-02-13 9 2 2 2
P066666666666 2016-02-10 6 3 3 3
P066666666666 2016-02-11 2 4 4 4
P066666666666 2016-02-14 2 4 4 5
P066666666666 2016-02-16 2 4 4 6
P066666666666 2016-02-12 1 7 5 7