一、创建表:

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的用法的更多相关文章

  1. Hive函数:LAG,LEAD,FIRST_VALUE,LAST_VALUE

    参考自大数据田地:http://lxw1234.com/archives/2015/04/190.htm 测试数据准备: create external table test_data ( cooki ...

  2. Hive 窗口函数、分析函数

    1 分析函数:用于等级.百分点.n分片等 Ntile 是Hive很强大的一个分析函数. 可以看成是:它把有序的数据集合 平均分配 到 指定的数量(num)个桶中, 将桶号分配给每一行.如果不能平均分配 ...

  3. hive窗口函数/分析函数详细剖析

    hive窗口函数/分析函数 在sql中有一类函数叫做聚合函数,例如sum().avg().max()等等,这类函数可以将多行数据按照规则聚集为一行,一般来讲聚集后的行数是要少于聚集前的行数的.但是有时 ...

  4. Hive 窗口函数

    举例: row_number() over(partition by clue_id order by state_updated desc) 业务举例: select distinct a.clue ...

  5. Hive 窗口函数LEAD LAG FIRST_VALUE LAST_VALUE

    窗口函数(window functions)对多行进行操作,并为查询中的每一行返回一个值. OVER()子句能将窗口函数与其他分析函数(analytical functions)和报告函数(repor ...

  6. Hive窗口函数保姆级教程

    在SQL中有一类函数叫做聚合函数,例如sum().avg().max()等等,这类函数可以将多行数据按照规则聚集为一行,一般来讲聚集后的行数是要少于聚集前的行数的.但是有时我们想要既显示聚集前的数据, ...

  7. Hive 窗口函数sum() over()求当前行和前面n条数据的和

    前几天遇到一个这样的需求:销售总占比加起来超过75%的top分类.具体需求是这样的:商品一级分类标签下面有许多商品标签,例如运动户外一级标签,下面可能存在361°,CBA,Nike,Adidas... ...

  8. Hive学习之路 (十六)Hive分析窗口函数(四) LAG、LEAD、FIRST_VALUE和LAST_VALUE

    数据准备 数据格式 cookie4.txt cookie1, ::,url2 cookie1, ::,url1 cookie1, ::,1url3 cookie1, ::,url6 cookie1, ...

  9. hive 取两次记录的时间差 lead lag first_value last_value

    -- LEAD(col,n,DEFAULT) 用于统计窗口内往下第n行值 -- 第一个参数为列名,第二个参数为往下第n行(可选,默认为1),第三个参数为默认值(当往下第n行为NULL时候,取默认值,如 ...

随机推荐

  1. java中的泛型1

    1.泛型概述 泛型,即“参数化类型”.一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参.那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数 ...

  2. JDBC(4)PreparedStatement

    PreparedStatement: 是一个预编译对象 是Statement的子接口 允许数据库预编译SQL 执行SQL的时候,无需重新传入SQL语句,它们已经编译SQL语句 执行SQL语句 :exe ...

  3. ElasticSearch5.0+版本分词热更新实践记录

    前言 刚开始接触ElasticSearch的时候,版本才是2.3.4,短短的时间,现在都更新到5.0+版本了.分词和head插件好像用法也不一样了,本博客记录如何配置Elasticsearch的Hea ...

  4. Redis启动问题解决方案

    linux下redis overcommit_memory的问题 我在启动Redis的时候出现如下警告信息. 警告信息:WARNING overcommit_memory is set to 0! B ...

  5. 【题解】洛谷P1198 [JSOI2008] 最大数(线段树)

    洛谷P1198:https://www.luogu.org/problemnew/show/P1198 思路 一道水水的线段树 20分钟A掉 这道题只涉及到单点修改和区间查询 所以这道题甚至不用Laz ...

  6. 第23章 I2C—读写EEPR

    本章参考资料:<STM32F76xxx参考手册>.<STM32F7xx规格书>.库帮助文档<STM32F779xx_User_Manual.chm>及<I2C ...

  7. [JavaScript]JS中的变量声明与有效域

    1.变量声明 var a = 1; //使用var声明变量 b = 1; //不使用var 第一种情况,在当前域中声明一个名为a的变量,如果实在方法内则为局部变量,若在最外层声明则a为全局变量. 第二 ...

  8. Drbd双机环境安装配置

    一.环境准备 1) 操作系统:ubuntu-14.04.1 x64 2) Ubuntu1 192.168.5.179 /dev/sdb1 主节点 Ubuntu2 192.168.5.178 /dev/ ...

  9. dubbox provider cosumer 包坐标及xml

    provider pom <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http:// ...

  10. kali linux 安装 Mysql Can't read from messagefile 报错解决方案

    1.下载安装包 下载地点:https://dev.mysql.com/downloads/mysql/ 或者 wget http://dev.mysql.com/get/Downloads/MySQL ...