Hive窗口函数

窗口函数语句简洁且功能强大,但并不被大家熟知。

概述

hive中的窗口函数和sql中的窗口函数类似,都是用来做一些数据分析类的工作,一般用于olap分析。
理解窗口函数可以从理解聚合函数开始,我们知道聚合函数的概念,就是将某列多行中的值按照聚合规则合并为一行,比如说Sum、AVG等等,简单的概念如图1所示。
avatar
通常来说,聚合后的行数都要小于聚合前的行数。
在sql中有一类函数叫做聚合函数,例如sum()、avg()、max()等等,这类函数可以将多行数据按照规则聚集为一行,一般来讲聚集后的行数是要少于聚集前的行数的。但是有时我们想要既显示聚集前的数据,又要显示聚集后的数据,这时我们便引入了窗口函数。
特性和好处:

  • 类似Group By的聚合
  • 非顺序的访问数据
  • 可以对于窗口函数使用分析函数、聚合函数和排名函数
  • 简化了SQL代码(消除Join)
  • 消除中间表

hive开窗函数over(partition by ……)用法

一、over(partition by ……)
主要和聚合函数sum()、count()、avg()等结合使用,实现分组聚合的功能
示例:根据day_id日期和mac_id机器码进行聚合分组求每一天的该机器的销量和即sum_num,hive sql语句:
select day_id,mac_id,mac_color,day_num,sum(day_num)over(partition by day_id,mac_id order by day_id) sum_num from test_temp_mac_id;
注:day_id,mac_id,mac_color,day_num为查询原有数据,sum_num为计算结果

day_id mac_id mac_color day_num sum_num
20171011 1292 金色 1 89
20171011 1292 金色 14 89
20171011 1292 金色 2 89
20171011 1292 金色 11 89
20171011 1292 黑色 2 89
20171011 1292 粉金 58 89
20171011 1292 金色 1 89
20171011 2013 金色 10 22
20171011 2013 金色 9 22
20171011 2013 金色 2 22
20171011 2013 金色 1 22
20171012 1292 金色 5 18
20171012 1292 金色 7 18
20171012 1292 金色 5 18
20171012 1292 粉金 1 18
20171012 2013 粉金 1 7
20171012 2013 金色 6 7
20171013 1292 黑色 1 1
20171013 2013 粉金 2 2
20171011 12460 茶花金 1 1

二、over(partition by ……)与group by 区别
如果用group by实现一中根据day_id日期和mac_id机器码进行聚合分组求每一天的该机器的销量和即sum_num,
则hive sql语句为:
select day_id,mac_id,sum(day_num) sum_num from test_temp_mac_id group by day_id,mac_id order by day_id;
注:我们可以观察到group by可以实现同样的分组聚合功能,但sql语句不能写与分组聚合无关的字段,否则会报错,即group by 与over(partition by ……)主要区别为,带上group by的hive sql语句只能显示与分组聚合相关的字段,而带上over(partition by ……)的hive sql语句能显示所有字段。

day_id mac_id sum_num
20171011 124609 1
20171011 20130 22
20171011 12922 89
20171012 12922 18
20171012 20130 7
20171013 12922 1
20171013 20130 2

hive中三个排序函数rank、row_number、dense_rank三者的区别

1、rank()函数
此排序方法进行排序时,相同的排序是一样的,而且下一个不同值是跳着排序的。
2、row_number()函数
此方法不管排名是否有相同的,都按照顺序1,2,3…..n
3、dense_rank()函数
此方法对于排名相同的名次一样,且后面名次不跳跃

a row_number rank dense_rank
A 1 1 1
C 2 2 2
D 3 3 3
B 4 3 3
E 5 5 4
F 6 6 5
G 7 7 6

时间戳

unix时间戳

unix时间戳是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒。
一个小时表示为UNIX时间戳格式为:3600秒;一天表示为UNIX时间戳为86400秒,闰秒不计算。

FROM_UNIXTIME(unix_timestamp,format)

把unix时间戳转换成date格式
示例:
hive>SELECT FROM_UNIXTIME( 1249488000, ‘%Y%m%d’ )
-> 20071120

UNIX_TIMESTAMP

UNIX_TIMESTAMP()
UNIX_TIMESTAMP(date)
如 果没有参数调用,返回一个Unix时间戳记(从’1970-01-01 00:00:00’GMT开始的秒数)。如果UNIX_TIMESTAMP()用一个date参数被调用,它返回从’1970-01-01 00:00:00’ GMT开始的秒数值。date可以是一个DATE字符串、一个DATETIME字符串、一个TIMESTAMP或以YYMMDD或YYYYMMDD格式的 本地时间的一个数字。
示例:
hive> select UNIX_TIMESTAMP();
-> 882226357
hive> select UNIX_TIMESTAMP(‘1997-10-04 22:23:00’);
-> 875996580
hive>select UNIX_TIMESTAMP(‘20071014’,’YYYYMMdd’)
-> 1169568500