6.7.4 窗口函数
1.相关函数说明
OVER():指定分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变而变化
CURRENT ROW:当前行
n PRECEDING:往前n行数据
n FOLLOWING:往后n行数据
UNBOUNDED:起点,UNBOUNDED PRECEDING 表示从前面的起点, UNBOUNDED FOLLOWING表示到后面的终点
LAG(col,n):往前第n行数据
LEAD(col,n):往后第n行数据
NTILE(n):把有序分区中的行分发到指定数据的组中,各个组有编号,编号从1开始,对于每一行,NTILE返回此行所属的组的编号。注意:n必须为int类型。
2.数据准备:name,orderdate,cost
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
3.需求
(1)查询在2017年4月份购买过的顾客及总人数
(2)查询顾客的购买明细及月购买总额
(3)上述的场景,要将cost按照日期进行累加
(4)查询顾客上次的购买时间
(5)查询前20%时间的订单信息
4.创建本地business.txt,导入数据
[atguigu@hadoop102 datas]$ vi business.txt
5.创建hive表并导入数据
create table business( name string, orderdate string, cost int ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
load data local inpath "/opt/module/datas/business.txt" into table business; |
6.按需求查询数据
(1)查询在2017年4月份购买过的顾客及总人数
select name,count(*) over () from business where substring(orderdate,1,7) = '2017-04' group by name; |
(2)查询顾客的购买明细及月购买总额
select name,orderdate,cost,sum(cost) over(partition by month(orderdate)) from business; |
(3)上述的场景,要将cost按照日期进行累加
select name,orderdate,cost, sum(cost) over() as sample1,--所有行相加 sum(cost) over(partition by name) as sample2,--按name分组,组内数据相加 sum(cost) over(partition by name order by orderdate) as sample3,--按name分组,组内数据累加 sum(cost) over(partition by name order by orderdate rows between UNBOUNDED PRECEDING and current row ) as sample4 ,--和sample3一样,由起点到当前行的聚合 sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING and current row) as sample5, --当前行和前面一行做聚合 sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING AND 1 FOLLOWING ) as sample6,--当前行和前边一行及后面一行 sum(cost) over(partition by name order by orderdate rows between current row and UNBOUNDED FOLLOWING ) as sample7 --当前行及后面所有行 from business; |
(4)查看顾客上次的购买时间
select name,orderdate,cost, lag(orderdate,1,'1900-01-01') over(partition by name order by orderdate ) as time1, lag(orderdate,2) over (partition by name order by orderdate) as time2 from business; |
(5)查询前20%时间的订单信息
select * from ( select name,orderdate,cost, ntile(5) over(order by orderdate) sorted from business ) t where sorted = 1; |
6.7.5 Rank
1.函数说明
RANK() 排序相同时会重复,总数不会变
DENSE_RANK() 排序相同时会重复,总数会减少
ROW_NUMBER() 会根据顺序计算
2.数据准备
表6-7 数据准备
name |
subject |
score |
孙悟空 |
语文 |
87 |
孙悟空 |
数学 |
95 |
孙悟空 |
英语 |
68 |
大海 |
语文 |
94 |
大海 |
数学 |
56 |
大海 |
英语 |
84 |
宋宋 |
语文 |
64 |
宋宋 |
数学 |
86 |
宋宋 |
英语 |
84 |
婷婷 |
语文 |
65 |
婷婷 |
数学 |
85 |
婷婷 |
英语 |
78 |
3.需求
计算每门学科成绩排名。
4.创建本地movie.txt,导入数据
[atguigu@hadoop102 datas]$ vi score.txt
5.创建hive表并导入数据
create table score( name string, subject string, score int) row format delimited fields terminated by " "; load data local inpath '/opt/module/datas/score.txt' into table score; |
6.按需求查询数据
select name, subject, score, rank() over(partition by subject order by score desc) rp, dense_rank() over(partition by subject order by score desc) drp, row_number() over(partition by subject order by score desc) rmp from score;
name subject score rp drp rmp 孙悟空 数学 95 1 1 1 宋宋 数学 86 2 2 2 婷婷 数学 85 3 3 3 大海 数学 56 4 4 4 宋宋 英语 84 1 1 1 大海 英语 84 1 1 2 婷婷 英语 78 3 2 3 孙悟空 英语 68 4 3 4 大海 语文 94 1 1 1 孙悟空 语文 87 2 2 2 婷婷 语文 65 3 3 3 宋宋 语文 64 4 4 4 |
1、hive常用的系统函数
1.1聚合函数
sum 求和
count 求个数
avg 求平均值
distinct 求不同值数
min 求最小值
max 求最大值
1.2 分析函数
rank
row_number
dense_rank
cume_dist
percent_rank
1.3 字符串连接函数
concat
concat_ws
collect_list
collect_set
1.4 其他函数
cast 类型转换
if 判断 if(con,'','')
1.1 collect_set 把同一分组的不同行的数据聚合成一个集合
1 hive (gmall)> select * from stud; 2 stud.name stud.area stud.course stud.score 3 zhang3 bj math 88 4 li4 bj math 99 5 wang5 sh chinese 92 6 zhao6 sh chinese 54 7 tian7 bj chinese 91
hive (gmall)> select course, collect_set(area), avg(score) from stud group by course;
chinese ["sh","bj"] 79.0
math ["bj"] 93.5
用下标可以取一个
1 hive (gmall)> select course, collect_set(area)[0], avg(score) from stud group by course; 2 chinese sh 79.0 3 math bj 93.5
1.2、日期处理函数
1.2.1、 data_format 日期格式化
1 hive (gmall)> select date_format('2019-02-10','yyyy-MM'); 2 2019-02
1.2.2、 data_add 加减日期
1 hive (gmall)> select date_add('2019-02-10',-1); 2 2019-02-09 3 hive (gmall)> select date_add('2019-02-10',1); 4 2019-02-11
1.2.3、 next_day
取当前天的下周的周一
1 hive (gmall)> select next_day('2019-02-12','MO'); 2 2019-02-18
取当前周的周一
hive (gmall)> select data_add(next_day('2019-02-12','MO')-7); 2019-02-18
1.2.4、 last_day 求当月最后一天的日期
1 hive (gmall)> select last_day('2019-02-10'); 2 2019-02-28
2排序
2.1 order by 全局排序 。一个reducer
2.2sort by 每个reducer内部排序,对全局结果集来说不是排序。
2.3distribute by 类似MR中的partition ,进行分区。结合sort by 使用。主义hive要求distribute by 语句要写在sort 语句前
1 先按照部门编号分区,再按照员工编号降序排序。 2 hive (default)> set mapreduce.job.reduces=3; 3 hive (default)> select * from emp distribute by deptno sort by empno desc
2.4 cluster by 当distribute by 和sort by 字段相同时。可以使用cluster by 。但是cluster by 排序只能是升序排序。
1 以下两种写法等价 2 hive (default)> select * from emp cluster by deptno; 3 hive (default)> select * from emp distribute by deptno sort by deptno; 4 注意:按照部门编号分区,不一定就是固定死的数值,可以是20号和30号部门分到一个分区里面去