Hive窗口函数之LAG、LEAD、FIRST_VALUE、LAST_VALUE的用法
一、创建表:
create table windows_ss
(
polno string,
eff_date string,
userno string
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
stored as textfile;
数据准备:
P066666666666,2016-04-02 09:00:02,user01
P066666666666,2016-04-02 09:00:00,user02
P066666666666,2016-04-02 09:03:04,user11
P066666666666,2016-04-02 09:50:05,user03
P066666666666,2016-04-02 10:00:00,user51
P066666666666,2016-04-02 09:10:00,user09
P066666666666,2016-04-02 09:50:01,user32
P088888888888,2016-04-02 09:00:02,user41
P088888888888,2016-04-02 09:00:00,user55
P088888888888,2016-04-02 09:03:04,user23
P088888888888,2016-04-02 09:50:05,user80
P088888888888,2016-04-02 10:00:00,user08
P088888888888,2016-04-02 09:10:00,user22
P088888888888,2016-04-02 09:50:01,user31
将数据导入Hive表中:
LOAD DATA LOCAL INPATH '/home/hadoop/testhivedata/windows_ss.txt' OVERWRITE INTO TABLE windows_ss;
LAG
LAG(col,n,DEFAULT) 用于统计窗口内往上第n行值
第一个参数为列名,第二个参数为往上第n行(可选,默认为1),第三个参数为默认值(当往上第n行为NULL时候,取默认值,如不指定,则为NULL)
SELECT
polno,
eff_date,
userno,
ROW_NUMBER() OVER(PARTITION BY polno ORDER BY eff_date) AS rn,
LAG(eff_date,1,'1970-01-01 00:00:00') OVER(PARTITION BY polno ORDER BY eff_date) AS last_1_time,
LAG(eff_date,2) OVER(PARTITION BY polno ORDER BY eff_date) AS last_2_time
FROM windows_ss;
结果:
polno eff_date userno rn last_1_time last_2_time
P066666666666 2016-04-02 09:00:00 user02 1 1970-01-01 00:00:00 NULL
P066666666666 2016-04-02 09:00:02 user01 2 2016-04-02 09:00:00 NULL
P066666666666 2016-04-02 09:03:04 user11 3 2016-04-02 09:00:02 2016-04-02 09:00:00
P066666666666 2016-04-02 09:10:00 user09 4 2016-04-02 09:03:04 2016-04-02 09:00:02
P066666666666 2016-04-02 09:50:01 user32 5 2016-04-02 09:10:00 2016-04-02 09:03:04
P066666666666 2016-04-02 09:50:05 user03 6 2016-04-02 09:50:01 2016-04-02 09:10:00
P066666666666 2016-04-02 10:00:00 user51 7 2016-04-02 09:50:05 2016-04-02 09:50:01
P088888888888 2016-04-02 09:00:00 user55 1 1970-01-01 00:00:00 NULL
P088888888888 2016-04-02 09:00:02 user41 2 2016-04-02 09:00:00 NULL
P088888888888 2016-04-02 09:03:04 user23 3 2016-04-02 09:00:02 2016-04-02 09:00:00
P088888888888 2016-04-02 09:10:00 user22 4 2016-04-02 09:03:04 2016-04-02 09:00:02
P088888888888 2016-04-02 09:50:01 user31 5 2016-04-02 09:10:00 2016-04-02 09:03:04
P088888888888 2016-04-02 09:50:05 user80 6 2016-04-02 09:50:01 2016-04-02 09:10:00
P088888888888 2016-04-02 10:00:00 user08 7 2016-04-02 09:50:05 2016-04-02 09:50:01
分析:
last_1_time: 指定了往上第1行的值,default为'1970-01-01 00:00:00'
P066666666666第一行,往上1行为NULL,因此取默认值 1970-01-01 00:00:00
P066666666666第三行,往上1行值为第二行值,2016-04-02 09:00:02
P066666666666第六行,往上1行值为第五行值,2016-04-02 09:50:01
last_2_time: 指定了往上第2行的值,为指定默认值
P088888888888第一行,往上2行为NULL
P088888888888第二行,往上2行为NULL
P088888888888第四行,往上2行为第二行值,2016-04-02 09:00:02
P088888888888第七行,往上2行为第五行值,2016-04-02 09:50:01
LEAD
与LAG相反
LEAD(col,n,DEFAULT) 用于统计窗口内往下第n行值
第一个参数为列名,第二个参数为往下第n行(可选,默认为1),第三个参数为默认值(当往下第n行为NULL时候,取默认值,如不指定,则为NULL)
SELECT
polno,
eff_date,
userno,
ROW_NUMBER() OVER(PARTITION BY polno ORDER BY eff_date) AS rn,
LEAD(eff_date,1,'1970-01-01 00:00:00') OVER(PARTITION BY polno ORDER BY eff_date) AS next_1_time,
LEAD(eff_date,2) OVER(PARTITION BY polno ORDER BY eff_date) AS next_2_time
FROM windows_ss;
结果:
polno eff_date userno rn next_1_time next_2_time
P066666666666 2016-04-02 09:00:00 user02 1 2016-04-02 09:00:02 2016-04-02 09:03:04
P066666666666 2016-04-02 09:00:02 user01 2 2016-04-02 09:03:04 2016-04-02 09:10:00
P066666666666 2016-04-02 09:03:04 user11 3 2016-04-02 09:10:00 2016-04-02 09:50:01
P066666666666 2016-04-02 09:10:00 user09 4 2016-04-02 09:50:01 2016-04-02 09:50:05
P066666666666 2016-04-02 09:50:01 user32 5 2016-04-02 09:50:05 2016-04-02 10:00:00
P066666666666 2016-04-02 09:50:05 user03 6 2016-04-02 10:00:00 NULL
P066666666666 2016-04-02 10:00:00 user51 7 1970-01-01 00:00:00 NULL
P088888888888 2016-04-02 09:00:00 user55 1 2016-04-02 09:00:02 2016-04-02 09:03:04
P088888888888 2016-04-02 09:00:02 user41 2 2016-04-02 09:03:04 2016-04-02 09:10:00
P088888888888 2016-04-02 09:03:04 user23 3 2016-04-02 09:10:00 2016-04-02 09:50:01
P088888888888 2016-04-02 09:10:00 user22 4 2016-04-02 09:50:01 2016-04-02 09:50:05
P088888888888 2016-04-02 09:50:01 user31 5 2016-04-02 09:50:05 2016-04-02 10:00:00
P088888888888 2016-04-02 09:50:05 user80 6 2016-04-02 10:00:00 NULL
P088888888888 2016-04-02 10:00:00 user08 7 1970-01-01 00:00:00 NULL
分析:
--逻辑与LAG一样,只不过LAG是往上,LEAD是往下
FIRST_VALUE
取分组内排序后,截止到当前行,第一个值
SELECT
polno,
eff_date,
userno,
ROW_NUMBER() OVER(PARTITION BY polno ORDER BY eff_date) AS rn,
FIRST_VALUE(userno) OVER(PARTITION BY polno ORDER BY eff_date) AS first1
FROM windows_ss;
polno eff_date userno rn first1
P066666666666 2016-04-02 09:00:00 user02 1 user02
P066666666666 2016-04-02 09:00:02 user01 2 user02
P066666666666 2016-04-02 09:03:04 user11 3 user02
P066666666666 2016-04-02 09:10:00 user09 4 user02
P066666666666 2016-04-02 09:50:01 user32 5 user02
P066666666666 2016-04-02 09:50:05 user03 6 user02
P066666666666 2016-04-02 10:00:00 user51 7 user02
P088888888888 2016-04-02 09:00:00 user55 1 user55
P088888888888 2016-04-02 09:00:02 user41 2 user55
P088888888888 2016-04-02 09:03:04 user23 3 user55
P088888888888 2016-04-02 09:10:00 user22 4 user55
P088888888888 2016-04-02 09:50:01 user31 5 user55
P088888888888 2016-04-02 09:50:05 user80 6 user55
P088888888888 2016-04-02 10:00:00 user08 7 user55
LAST_VALUE
取分组内排序后,截止到当前行,最后一个值
SELECT
polno,
eff_date,
userno,
ROW_NUMBER() OVER(PARTITION BY polno ORDER BY eff_date) AS rn,
LAST_VALUE(userno) OVER(PARTITION BY polno ORDER BY eff_date) AS last1
FROM windows_ss;
结果:
polno eff_date userno rn last1
P066666666666 2016-04-02 09:00:00 user02 1 user02
P066666666666 2016-04-02 09:00:02 user01 2 user01
P066666666666 2016-04-02 09:03:04 user11 3 user11
P066666666666 2016-04-02 09:10:00 user09 4 user09
P066666666666 2016-04-02 09:50:01 user32 5 user32
P066666666666 2016-04-02 09:50:05 user03 6 user03
P066666666666 2016-04-02 10:00:00 user51 7 user51
P088888888888 2016-04-02 09:00:00 user55 1 user55
P088888888888 2016-04-02 09:00:02 user41 2 user41
P088888888888 2016-04-02 09:03:04 user23 3 user23
P088888888888 2016-04-02 09:10:00 user22 4 user22
P088888888888 2016-04-02 09:50:01 user31 5 user31
P088888888888 2016-04-02 09:50:05 user80 6 user80
P088888888888 2016-04-02 10:00:00 user08 7 user08
如果不指定ORDER BY,则默认按照记录在文件中的偏移量进行排序,会出现错误的结果
FIRST_VALUE没有排序:
SELECT
polno,
eff_date,
userno,
FIRST_VALUE(userno) OVER(PARTITION BY polno) AS first2
FROM windows_ss;
polno eff_date userno first2
P066666666666 2016-04-02 09:00:02 user01 user01
P066666666666 2016-04-02 09:00:00 user02 user01
P066666666666 2016-04-02 09:03:04 user11 user01
P066666666666 2016-04-02 09:50:05 user03 user01
P066666666666 2016-04-02 10:00:00 user51 user01
P066666666666 2016-04-02 09:10:00 user09 user01
P066666666666 2016-04-02 09:50:01 user32 user01
P088888888888 2016-04-02 09:00:02 user41 user41
P088888888888 2016-04-02 09:00:00 user55 user41
P088888888888 2016-04-02 09:03:04 user23 user41
P088888888888 2016-04-02 09:50:05 user80 user41
P088888888888 2016-04-02 10:00:00 user08 user41
P088888888888 2016-04-02 09:10:00 user22 user41
P088888888888 2016-04-02 09:50:01 user31 user41
LAST_VALUE没有排序:
SELECT
polno,
eff_date,
userno,
LAST_VALUE(userno) OVER(PARTITION BY polno) AS last2
FROM windows_ss;
结果:
polno eff_date userno last2
P066666666666 2016-04-02 09:00:02 user01 user32
P066666666666 2016-04-02 09:00:00 user02 user32
P066666666666 2016-04-02 09:03:04 user11 user32
P066666666666 2016-04-02 09:50:05 user03 user32
P066666666666 2016-04-02 10:00:00 user51 user32
P066666666666 2016-04-02 09:10:00 user09 user32
P066666666666 2016-04-02 09:50:01 user32 user32
P088888888888 2016-04-02 09:00:02 user41 user31
P088888888888 2016-04-02 09:00:00 user55 user31
P088888888888 2016-04-02 09:03:04 user23 user31
P088888888888 2016-04-02 09:50:05 user80 user31
P088888888888 2016-04-02 10:00:00 user08 user31
P088888888888 2016-04-02 09:10:00 user22 user31
P088888888888 2016-04-02 09:50:01 user31 user31
如果想要取分组内排序后最后一个值,则需要变通一下:
SELECT
polno,
eff_date,
userno,
ROW_NUMBER() OVER(PARTITION BY polno ORDER BY eff_date) AS rn,
LAST_VALUE(userno) OVER(PARTITION BY polno ORDER BY eff_date) AS last1,
FIRST_VALUE(userno) OVER(PARTITION BY polno ORDER BY eff_date DESC) AS last2
FROM windows_ss ORDER BY polno,eff_date;
polno eff_date userno rn last1 last2
P066666666666 2016-04-02 09:00:00 user02 1 user02 user51
P066666666666 2016-04-02 09:00:02 user01 2 user01 user51
P066666666666 2016-04-02 09:03:04 user11 3 user11 user51
P066666666666 2016-04-02 09:10:00 user09 4 user09 user51
P066666666666 2016-04-02 09:50:01 user32 5 user32 user51
P066666666666 2016-04-02 09:50:05 user03 6 user03 user51
P066666666666 2016-04-02 10:00:00 user51 7 user51 user51
P088888888888 2016-04-02 09:00:00 user55 1 user55 user08
P088888888888 2016-04-02 09:00:02 user41 2 user41 user08
P088888888888 2016-04-02 09:03:04 user23 3 user23 user08
P088888888888 2016-04-02 09:10:00 user22 4 user22 user08
P088888888888 2016-04-02 09:50:01 user31 5 user31 user08
P088888888888 2016-04-02 09:50:05 user80 6 user80 user08
P088888888888 2016-04-02 10:00:00 user08 7 user08 user08
注意:
在使用分析函数的过程中,要特别注意ORDERBY子句,用的不恰当,统计出的结果就不是你所期望的
Hive窗口函数之LAG、LEAD、FIRST_VALUE、LAST_VALUE的用法的更多相关文章
- Hive函数:LAG,LEAD,FIRST_VALUE,LAST_VALUE
参考自大数据田地:http://lxw1234.com/archives/2015/04/190.htm 测试数据准备: create external table test_data ( cooki ...
- Hive 窗口函数、分析函数
1 分析函数:用于等级.百分点.n分片等 Ntile 是Hive很强大的一个分析函数. 可以看成是:它把有序的数据集合 平均分配 到 指定的数量(num)个桶中, 将桶号分配给每一行.如果不能平均分配 ...
- hive窗口函数/分析函数详细剖析
hive窗口函数/分析函数 在sql中有一类函数叫做聚合函数,例如sum().avg().max()等等,这类函数可以将多行数据按照规则聚集为一行,一般来讲聚集后的行数是要少于聚集前的行数的.但是有时 ...
- Hive 窗口函数
举例: row_number() over(partition by clue_id order by state_updated desc) 业务举例: select distinct a.clue ...
- Hive 窗口函数LEAD LAG FIRST_VALUE LAST_VALUE
窗口函数(window functions)对多行进行操作,并为查询中的每一行返回一个值. OVER()子句能将窗口函数与其他分析函数(analytical functions)和报告函数(repor ...
- Hive窗口函数保姆级教程
在SQL中有一类函数叫做聚合函数,例如sum().avg().max()等等,这类函数可以将多行数据按照规则聚集为一行,一般来讲聚集后的行数是要少于聚集前的行数的.但是有时我们想要既显示聚集前的数据, ...
- Hive 窗口函数sum() over()求当前行和前面n条数据的和
前几天遇到一个这样的需求:销售总占比加起来超过75%的top分类.具体需求是这样的:商品一级分类标签下面有许多商品标签,例如运动户外一级标签,下面可能存在361°,CBA,Nike,Adidas... ...
- Hive学习之路 (十六)Hive分析窗口函数(四) LAG、LEAD、FIRST_VALUE和LAST_VALUE
数据准备 数据格式 cookie4.txt cookie1, ::,url2 cookie1, ::,url1 cookie1, ::,1url3 cookie1, ::,url6 cookie1, ...
- hive 取两次记录的时间差 lead lag first_value last_value
-- LEAD(col,n,DEFAULT) 用于统计窗口内往下第n行值 -- 第一个参数为列名,第二个参数为往下第n行(可选,默认为1),第三个参数为默认值(当往下第n行为NULL时候,取默认值,如 ...
随机推荐
- oracle中PLSQL存储过程中如何使用逗号分隔的集合(逗号分隔字符串转换为一个集合)
原文: https://blogs.oracle.com/aramamoo/entry/how_to_split_comma_separated_string_and_pass_to_in_claus ...
- PhoneGap Geolocation结合百度地图api获取地理位置api
一.使用百度地图API 1.地址:http://developer.baidu.com/map/ 2.在js DEMO中获取反地址解析的DEMO 3.修改这个DEMO的密钥,去创建应用就能创建密钥,然 ...
- BZOJ2662:[BJWC2012]冻结(分层图最短路)
Description “我要成为魔法少女!” “那么,以灵魂为代价,你希望得到什么?” “我要将有关魔法和奇迹的一切,封印于卡片之中„„” 在这个愿望被实现以后的世界里,人们享 ...
- 根据用户id生成一个唯一邀请码
需求描述:根据用户id生成与之对应的唯一邀请码,范围为‘0-9A-Z’. 这个需求的重点在于加粗的部分,也就是要能够根据邀请码反推出用户ID,这样邀请码就不用入库了,在用户量很大的情况下,性能可以得到 ...
- C# 实现Excel读取接口写入数据
[Route("adm/getInfo")] [HttpGet] public string GetInfo() { var types = typeof(GCP.Server.W ...
- 安装jdk1.7
1.压缩文件放到/usr文件夹里 2.解压到 /usr里,tar -zxvf jdk-7u71-linux-i586.tar.gz 3.配置jdk环境变量,打开/etc/profile配置文件,将下面 ...
- 【题解】洛谷P1052 [NOIP2005TG] 过河(DP+离散化)
题目来源:洛谷P1052 思路 一开始觉得是贪心 但是仔细一想不对 是DP 再仔细一看数据不对 有点大 如果直接存下的话 显然会炸 那么就需要考虑离散化 因为一步最大跳10格 那么我们考虑从1到10都 ...
- 使用BSRR和BRR寄存器直接操作STM32的I/O端口
STM32的每个GPIO端口都有两个特别的寄存器,GPIOx_BSRR和GPIOx_BRR寄存器,通过这两个寄存器可以直接对对应的GPIOx端口置'1'或置'0'. GPIOx_BSRR的高16位中每 ...
- 『C++』Temp_2018_12_26
#include <iostream> #include <string> #include <array> using namespace std; class ...
- vector 定义的二维数组的遍历
之前我们分享了STL的一些容器,再介绍vector中只介绍了二维的vector的定义并没有说二维的vector怎么遍历,那么我们今天就来看下二维的vector怎么遍历 看下面的代码吧. #includ ...