hive表之简单窗口函数 over()

  • 窗口函数通常是分析人员使用 hive ql 进行一些复杂逻辑计算时使用的特殊函数,其中 over() 通常与聚合函数共同使用,比如 count()、sum()、min()、max()、avg() 等。
  • over() 具有一定的窗口语义,如:OVER(ROWS ((CURRENT ROW) | (UNBOUNDED) PRECEDING) AND (UNBOUNDED |(CURRENT ROW) ) FOLLOWING )
  • over() 直接使用时,通常是指定全量数据,当我们想要按某列的不同值进行窗口划分时,可以在 over() 中加入 partition by 语句。
  • 常用 over() 内部参数:
1. PARTITION BY
2. ORDER BY
3. ROWS ((CURRENT ROW) | (UNBOUNDED) PRECEDING) AND (UNBOUNDED |(CURRENT ROW) ) FOLLOWING 

示例

创建测试表并加载简单的示例数据进行演示:

hive> create table recommend.test_window(logday string, userid string, score int)
    > row format delimited
    > Fields terminated by ',';
logday      userid  score
20191020    11111   85
20191020    22222   83
20191020    33333   86
20191021    11111   87
20191021    22222   65
20191021    33333   98
20191022    11111   67
20191022    22222   34
20191022    33333   88
20191023    11111   99
20191023    22222   33

示例 1: 简单使用 over() 函数进行数据统计, 统计每个用户及表中数据的总数。

hive> select logday, userid, score, count(*) over()  as total
    > from recommend.test_window;

OK
logday      userid  score total
20191023    22222   33  11
20191023    11111   99  11
20191022    33333   88  11
20191022    22222   34  11
20191022    11111   67  11
20191021    33333   98  11
20191021    22222   65  11
20191021    11111   87  11
20191020    33333   86  11
20191020    22222   83  11
20191020    11111   85  11
  • 这里使用 over() 与 select count(*) 有相同的作用,好处就是,在需要列出所有列值时不用再进行一次关联。

示例 2: 当想要对每天的数据进行统计时,可以使用 partition by 按日期列对数据进行分区处理,如:over(partition by logday)

hive> select logday, userid, count(userid) over(partition by logday) as total
    > from recommend.test_window;

OK
logday      userid  total
20191020    33333   3
20191020    22222   3
20191020    11111   3
20191021    33333   3
20191021    22222   3
20191021    11111   3
20191022    33333   3
20191022    22222   3
20191022    11111   3
20191023    22222   2
20191023    11111   2
  • 这种用法与 select logday, count(userid) from recommend.test_window group by logday 具有相同的效果,但是当想要得到 userid 信息时,这种用法的优势就很明显。

示例 3: 下面我们想要得到从第一天到现在的所有 score 大于80分的用户总数,此时简单的分区不能满足需求,需要将 order by 和 窗口定义结合使用。

hive>
    > select logday,
    >         count(userid) over(order by logday rows between unbounded preceding and current row)
    > from recommend.test_window
    > where score > 80;
    
OK
20191020    1
20191020    2
20191020    3
20191021    4
20191021    5
20191022    6
20191023    7
  • 通过 over() 计算出按日期的累加值后,然后去每天的最大值就是需要的总的累加值。

示例 4:计算每个用户到当前日期分数大于80的天数。

hive> select userid, logday, score, count(case when score>=80 then userid else null end) over(partition by userid                 order by logday rows between unbounded preceding and current row) as total
    > from recommend.test_window
    > order by logday, userid;
    
useri   logday      score   total
11111   20191020    85  1
22222   20191020    83  1
33333   20191020    86  1
11111   20191021    87  2
22222   20191021    65  1
33333   20191021    98  2
11111   20191022    67  2
22222   20191022    34  1
33333   20191022    88  3
11111   20191023    99  3
22222   20191023    33  1

扩展

  • 分区语句 partition by 除了这里使用的单列分区外,还可以使用多列分区。事实上,这里的分区跟创建 hive 分区表有异曲同工之妙。
  • 窗口的划分除了上面使用的 rows between unbounded preceding and current row 之外,还有其他的使用场景,如:
ROWS BETWEEN CURRENT ROW AND n FOLLOWING:从当前行到随后的n行  
ROWS BETWEEN n PRECEDING AND CURRENT ROW:从前n行到当前行  
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING: 从当前行到结尾行 

小结

  • 窗口函数通常是在复杂的分析场景中使用的,熟练掌握其用法,可以大大提升分析人员的工作效率。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,386评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,142评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,704评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,702评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,716评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,573评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,314评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,230评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,680评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,873评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,991评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,706评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,329评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,910评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,038评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,158评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,941评论 2 355