一、相关函数说明:
1、cover():指定分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变而变化
2、current row:当前行
- n PRECEDING:往前n行数据
- n FOLLOWING:往后n行数据
3、UNBOUNDED:起点,UNBOUNDED PROCEDING 表示从前面的起点,UNBOUNDED FOLLOWING:表示到后面的终点
4、LAG(col,n):往前第n行数据
5、LEAD(col,n):往后第n行数据
6、NTILE(n):把有序分区中的行分发到指定数据的组中,各个组有编号,编号从1开始,对于每一行,NTILE返回慈航所属的组的编号。注意:n必须为int类型。
二、数据准备:
- 在/home/hadoop/data目录下创建一份business.txt文件
2.1、建表语句:
create table business (
name string,
oderdate string,
cost int
)ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
2.2、导入数据到表中:
load data local inpath '/home/hadoop/data/business,txt' into table business;
2.3、business.txt的表内容
jack,2019-01-01,10
tony,2019-01-02,15
jack,2019-02-03,23
tony,2019-01-04,29
jack,2019-01-05,46
jack,2019-04-06,42
tony,2019-01-07,50
jack,2019-01-08,55
mart,2019-04-08,62
mart,2019-04-09,68
neil,2019-05-10,12
mart,2019-04-11,75
neil,2019-06-12,80
mart,2019-04-13,94
三、需求:
(1)、查询在2019年4月份购买过的顾客及人数总数
(2)、查询顾客的购买明细及月购买总额
(3)、上述的场景,要将cost按照日期进行累加
(4)、查询顾客上次的购买时间
(5)、查询前20%时间的订单信息
四、开始进行需求分析
4.1、查询在2019年4月份购买过的顾客及人数总数
select name,count(*) over()
from business
where substring(orderdate,1,7) = '2019-04'
group by name;
输出结果:
- mart 2
- jack 2
4.2、查询顾客的购买明细及月购买总额
select name,orderdate,cost,sum(cost) over(partition by month(orderdate)) from business;
输出结果如下:
name orderdate cost sum
jack 2019-01-01 10 205
jack 2019-01-08 55 205
tony 2019-01-07 50 205
jack 2019-01-05 46 205
tony 2019-01-04 29 205
tony 2019-01-02 15 205
jack 2019-02-03 23 23
mart 2019-04-13 94 341
jack 2019-04-06 42 341
mart 2019-04-11 75 341
mart 2019-04-09 68 341
mart 2019-04-08 62 341
neil 2019-05-10 12 12
neil 2019-06-12 80 80
4.3、上述的场景中,我们要将cost(消费金额)按照日期进行累加:
select name,orderdate,cost,sum(cost)
over() as sample 1 //所有行数相加
from business;
输出结果如下:
mart 2019-04-13 94 661
neil 2019-06-12 80 661
mart 2019-04-11 75 661
neil 2019-05-10 12 661
mart 2019-04-09 68 661
mart 2019-04-08 62 661
jack 2019-01-08 55 661
tony 2019-01-07 50 661
jack 2019-04-06 42 661
jack 2019-01-05 46 661
tony 2019-01-04 29 661
jack 2019-02-03 23 661
tony 2019-01-02 15 661
jack 2019-01-01 10 661
4.3.2、按照name分组,组内数据相加
select name,orderdate,cost,sum(cost)
over(partition by name) as sample2
from business;
输出结果:
jack 2019-01-05 46 176
jack 2019-01-08 55 176
jack 2019-01-01 10 176
jack 2019-04-06 42 176
jack 2019-02-03 23 176
mart 2019-04-13 94 299
mart 2019-04-11 75 299
mart 2019-04-09 68 299
mart 2019-04-08 62 299
neil 2019-05-10 12 92
neil 2019-06-12 80 92
tony 2019-01-04 29 94
tony 2019-01-02 15 94
tony 2019-01-07 50 94
4.3.3、按照name分组,组内数据累加:
select name,orderdate,cost,
sun(cost) over(partition by name order by orderdate) as sample3
from business;
输出结果如下:
jack 2019-01-01 10 10
jack 2019-01-05 46 56
jack 2019-01-08 55 111
jack 2019-02-03 23 134
jack 2019-04-06 42 176
mart 2019-04-08 62 62
mart 2019-04-09 68 130
mart 2019-04-11 75 205
mart 2019-04-13 94 299
neil 2019-05-10 12 12
neil 2019-06-12 80 92
tony 2019-01-02 15 15
tony 2019-01-04 29 44
tony 2019-01-07 50 94
4.3.4、和sample3一样,由七点到当前行的聚合
select name,orderdate,cost,
sum(cost) over(partition by name order by orderdate rows between UNBOUNDED PRECEDING and current row) as sample4
输出结果:
jack 2019-01-01 10 10
jack 2019-01-05 46 56
jack 2019-01-08 55 111
jack 2019-02-03 23 134
jack 2019-04-06 42 176
mart 2019-04-08 62 62
mart 2019-04-09 68 130
mart 2019-04-11 75 205
mart 2019-04-13 94 299
neil 2019-05-10 12 12
neil 2019-06-12 80 92
tony 2019-01-02 15 15
tony 2019-01-04 29 44
tony 2019-01-07 50 94
4.3.5、当前行和前面一行做聚合
select name,orderdate,cost,
sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING and current row) as sample5
from business;
输出结果:
jack 2019-01-01 10 10
jack 2019-01-05 46 56
jack 2019-01-08 55 101
jack 2019-02-03 23 78
jack 2019-04-06 42 65
mart 2019-04-08 62 62
mart 2019-04-09 68 130
mart 2019-04-11 75 143
mart 2019-04-13 94 169
neil 2019-05-10 12 12
neil 2019-06-12 80 92
tony 2019-01-02 15 15
tony 2019-01-04 29 44
tony 2019-01-07 50 79
4.3.6、当前行和前面一行及后面一行
select name,orderdate,cost,
sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING AND 1 FOLLOWING) as sample6
from business;
输出结果:
jack 2019-01-01 10 56
jack 2019-01-05 46 111
jack 2019-01-08 55 124
jack 2019-02-03 23 120
jack 2019-04-06 42 65
mart 2019-04-08 62 130
mart 2019-04-09 68 205
mart 2019-04-11 75 237
mart 2019-04-13 94 169
neil 2019-05-10 12 92
neil 2019-06-12 80 92
tony 2019-01-02 15 44
tony 2019-01-04 29 94
tony 2019-01-07 50 79
4.3.6、当前行及后面所有行
select name,orderdate,cost,
sum(cost) over(partition by name order by orderdate rows between current row and UNBOUNDED FOLLOWING) as sample7
from business;
输出结果:
jack 2019-01-01 10 176
jack 2019-01-05 46 166
jack 2019-01-08 55 120
jack 2019-02-03 23 65
jack 2019-04-06 42 42
mart 2019-04-08 62 299
mart 2019-04-09 68 237
mart 2019-04-11 75 169
mart 2019-04-13 94 94
neil 2019-05-10 12 92
neil 2019-06-12 80 80
tony 2019-01-02 15 94
tony 2019-01-04 29 79
tony 2019-01-07 50 50
五、查看顾客的上次的购买时间:
SQL代码如下:
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
form business;
输出结果:
jack 2019-01-01 10 1900-01-01 NULL
jack 2019-01-05 46 2019-01-01 NULL
jack 2019-01-08 55 2019-01-05 2019-01-01
jack 2019-02-03 23 2019-01-08 2019-01-05
jack 2019-04-06 42 2019-02-03 2019-01-08
mart 2019-04-08 62 1900-01-01 NULL
mart 2019-04-09 68 2019-04-08 NULL
mart 2019-04-11 75 2019-04-09 2019-04-08
mart 2019-04-13 94 2019-04-11 2019-04-09
neil 2019-05-10 12 1900-01-01 NULL
neil 2019-06-12 80 2019-05-10 NULL
tony 2019-01-02 15 1900-01-01 NULL
tony 2019-01-04 29 2019-01-02 NULL
tony 2019-01-07 50 2019-01-04 2019-01-02
六、查询前20%时间的订单信息
select * from (
select name,orderdate,cost,ntile(5) over(order by orderdate) sorted
from business
) t
where sorted = 1;
输出结果如下:
jack 2019-01-01 10 1
tony 2019-01-02 15 1
tony 2019-01-04 29 1