Hive 窗口函数

Select 窗口函数

over():指定分析函数的数据窗口大小,这个数据窗口大小随行的变化而变化。
CURRENT ROW:当前行
n PRECEDING:往前n行(包含其间所有)
n FOLLOWING:往后n行(包含其间所有)
UNBOUNDED PRECEDING:表示从前面的起点开始
UNBOUNDED FOLLOWING:表示到后面的终点开始
LAG(col,n):往前第n行数据
LEAD(col,n):往后第n行数据
NTILE(n):分n组,并给分组编号

示例准备 --------------------------------------

business.txt

jack,2017-01-01,10
tony,2017-01-02,15
jack,2017-02-03,23
tony,2017-01-04,29
jack,2017-01-05,46
jack,2017-04-06,42
tony,2017-01-07,50
jack,2017-01-08,55
mart,2017-04-08,62
mart,2017-04-09,68
neil,2017-05-10,12
mart,2017-04-11,75
neil,2017-06-12,80
mart,2017-04-13,94

hive> create table business(name string, orderdate string, cost int)
row format delimited
fields terminated by ',';
hive> load data local inpath '/home/user000/data/business.txt' into table business;

查询在2017年4月购买过的顾客及总人数

错误:hive> select name,count(1) from business where substring(orderdate,1,7) = '2017-04' group by name;
+-------+------+--+
| name | _c1 |
+-------+------+--+
| jack | 1 |
| mart | 4 |
+-------+------+--+
正确:hive> select name,count(1) over() from business where substring(orderdate,1,7) = '2017-04' group by name;
+-------+---------+--+
| name | _wcol0 |
+-------+---------+--+
| mart | 2 |
| jack | 2 |
+-------+---------+--+
解释:group by name后窗口是2个,所以加一个over指定窗口,然后count就能得到正确答案。
如果不加,每个name下有各自的记录,count是分别计算每个name下的记录。

查询顾客的购买明细及月购买总额

hive(default)> select *,sum(cost) over(partition by month(orderdate)) from business;
hive(default)> select *,sum(cost) over(distribute by month(orderdate)) from business;
+----------------+---------------------+----------------+---------+--+
| business.name | business.orderdate | business.cost | _wcol0 |
+----------------+---------------------+----------------+---------+--+
| jack | 2017-01-01 | 10 | 205 |
| jack | 2017-01-08 | 55 | 205 |
| tony | 2017-01-07 | 50 | 205 |
| jack | 2017-01-05 | 46 | 205 |
| tony | 2017-01-04 | 29 | 205 |
| tony | 2017-01-02 | 15 | 205 |
| jack | 2017-02-03 | 23 | 23 |
| mart | 2017-04-13 | 94 | 341 |
| jack | 2017-04-06 | 42 | 341 |
| mart | 2017-04-11 | 75 | 341 |
| mart | 2017-04-09 | 68 | 341 |
| mart | 2017-04-08 | 62 | 341 |
| neil | 2017-05-10 | 12 | 12 |
| neil | 2017-06-12 | 80 | 80 |
+----------------+---------------------+----------------+---------+--+
解释:partition by orderdate会根据日期分区,使用partition by month(orderdate)按月分区。

上述的场景,要将cost按照日期进行累加

hive(default)> select *,sum(cost) over(sort by orderdate rows between UNBOUNDED PRECEDING and CURRENT ROW) from business;
+----------------+---------------------+----------------+---------+--+
| business.name | business.orderdate | business.cost | _wcol0 |
+----------------+---------------------+----------------+---------+--+
| jack | 2017-01-01 | 10 | 10 |
| tony | 2017-01-02 | 15 | 25 |
| tony | 2017-01-04 | 29 | 54 |
| jack | 2017-01-05 | 46 | 100 |
| tony | 2017-01-07 | 50 | 150 |
| jack | 2017-01-08 | 55 | 205 |
| jack | 2017-02-03 | 23 | 228 |
| jack | 2017-04-06 | 42 | 270 |
| mart | 2017-04-08 | 62 | 332 |
| mart | 2017-04-09 | 68 | 400 |
| mart | 2017-04-11 | 75 | 475 |
| mart | 2017-04-13 | 94 | 569 |
| neil | 2017-05-10 | 12 | 581 |
| neil | 2017-06-12 | 80 | 661 |
+----------------+---------------------+----------------+---------+--+

按名字统计,每个人的累加:
+----------------+---------------------+----------------+---------+--+
| business.name | business.orderdate | business.cost | _wcol0 |
+----------------+---------------------+----------------+---------+--+
| jack | 2017-01-01 | 10 | 10 |
| jack | 2017-01-05 | 46 | 56 |
| jack | 2017-01-08 | 55 | 111 |
| jack | 2017-02-03 | 23 | 134 |
| jack | 2017-04-06 | 42 | 176 |
| mart | 2017-04-08 | 62 | 62 |
| mart | 2017-04-09 | 68 | 130 |
| mart | 2017-04-11 | 75 | 205 |
| mart | 2017-04-13 | 94 | 299 |
| neil | 2017-05-10 | 12 | 12 |
| neil | 2017-06-12 | 80 | 92 |
| tony | 2017-01-02 | 15 | 15 |
| tony | 2017-01-04 | 29 | 44 |
| tony | 2017-01-07 | 50 | 94 |
+----------------+---------------------+----------------+---------+--+

查询顾客上次的购买时间

hive(default)> select name,orderdate,lag(orderdate,1) over(distribute by name sort by orderdate) from business;
+-------+-------------+-------------+--+
| name | orderdate | _wcol0 |
+-------+-------------+-------------+--+
| jack | 2017-01-01 | NULL |
| jack | 2017-01-05 | 2017-01-01 |
| jack | 2017-01-08 | 2017-01-05 |
| jack | 2017-02-03 | 2017-01-08 |
| jack | 2017-04-06 | 2017-02-03 |
| mart | 2017-04-08 | NULL |
| mart | 2017-04-09 | 2017-04-08 |
| mart | 2017-04-11 | 2017-04-09 |
| mart | 2017-04-13 | 2017-04-11 |
| neil | 2017-05-10 | NULL |
| neil | 2017-06-12 | 2017-05-10 |
| tony | 2017-01-02 | NULL |
| tony | 2017-01-04 | 2017-01-02 |
| tony | 2017-01-07 | 2017-01-04 |
+-------+-------------+-------------+--+

lead示例:
hive(default)> select name,orderdate,lead(orderdate,1) over(distribute by name sort by orderdate) from business;
+-------+-------------+-------------+--+
| name | orderdate | _wcol0 |
+-------+-------------+-------------+--+
| jack | 2017-01-01 | 2017-01-05 |
| jack | 2017-01-05 | 2017-01-08 |
| jack | 2017-01-08 | 2017-02-03 |
| jack | 2017-02-03 | 2017-04-06 |
| jack | 2017-04-06 | NULL |
| mart | 2017-04-08 | 2017-04-09 |
| mart | 2017-04-09 | 2017-04-11 |
| mart | 2017-04-11 | 2017-04-13 |
| mart | 2017-04-13 | NULL |
| neil | 2017-05-10 | 2017-06-12 |
| neil | 2017-06-12 | NULL |
| tony | 2017-01-02 | 2017-01-04 |
| tony | 2017-01-04 | 2017-01-07 |
| tony | 2017-01-07 | NULL |
+-------+-------------+-------------+--+

查询前20%的订单信息

ntile(5),然后取第一组,就是20%了。
hive(default)> select name,orderdate,cost,ntile(5) over(sort by orderdate) from business;
+-------+-------------+-------+---------+--+
| name | orderdate | cost | _wcol0 |
+-------+-------------+-------+---------+--+
| jack | 2017-01-01 | 10 | 1 |
| tony | 2017-01-02 | 15 | 1 |
| tony | 2017-01-04 | 29 | 1 |
| jack | 2017-01-05 | 46 | 2 |
| tony | 2017-01-07 | 50 | 2 |
| jack | 2017-01-08 | 55 | 2 |
| jack | 2017-02-03 | 23 | 3 |
| jack | 2017-04-06 | 42 | 3 |
| mart | 2017-04-08 | 62 | 3 |
| mart | 2017-04-09 | 68 | 4 |
| mart | 2017-04-11 | 75 | 4 |
| mart | 2017-04-13 | 94 | 4 |
| neil | 2017-05-10 | 12 | 5 |
| neil | 2017-06-12 | 80 | 5 |
+-------+-------------+-------+---------+--+

hive(default)> select * from
(select name,orderdate,cost,ntile(5) over(sort by orderdate) gid from business ) t
where gid = 1;
+---------+--------------+---------+--------+--+
| t.name | t.orderdate | t.cost | t.gid |
+---------+--------------+---------+--------+--+
| jack | 2017-01-01 | 10 | 1 |
| tony | 2017-01-02 | 15 | 1 |
| tony | 2017-01-04 | 29 | 1 |
+---------+--------------+---------+--------+--+

RANK() DENSE_RANK() ROW_NUMBER()

RANK():排序相同时会重复,总数不会变,例如排序结果是 1 1 3 4
DENSE_RANK():排序相同时,总数会减少,例如排序结果是 1 1 2 3
ROW_NUMBER():行号

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

推荐阅读更多精彩内容

  • 1.输入结果等于输出结果2.类似Group By的聚合3.非顺序的访问数据4.可以对于窗口函数使用分析函数 聚合函...
    时待吾阅读 1,057评论 0 0
  • CNBLUEone阅读 221评论 0 0
  • 2017年5月24日 晴转雨 起床时间5:45 我起床时看到妈妈在拖地板,我就搬来的我的小桌子开始早读。读了《唐诗...
    泥养万物阅读 1,226评论 1 3
  • 作业1: 好好回想一下,小时候呆呆看过什么。挑选一个印象或一幅画面写出来。 幼时并不善于观察,发呆。最近迷上了健身...
    折翼的拨浪鼓阅读 226评论 3 0