版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/debimeng/article/details/87904542
HiveSQL题:
求单月访问次数和总访问次数
数据如下:
A,2015-01,5
A,2015-01,15
B,2015-01,5
A,2015-01,8
B,2015-01,25
A,2015-01,5
A,2015-02,4
A,2015-02,6
B,2015-02,10
B,2015-02,5
A,2015-03,16
A,2015-03,22
B,2015-03,23
B,2015-03,10
B,2015-03,1
数据格式说明:用户名,月份,访问次数
解答:
create table tb_access(name varchar2(20),mon varchar2(20),num int);
insert into tb_access values('A','2018-01',5);
insert into tb_access values('A','2018-01',15);
insert into tb_access values('B','2018-01',5);
insert into tb_access values('A','2018-01',8);
insert into tb_access values('B','2018-01',25);
insert into tb_access values('A','2018-01',5);
insert into tb_access values('A','2018-02',4);
insert into tb_access values('A','2018-02',6);
insert into tb_access values('B','2018-02',10);
insert into tb_access values('B','2018-02',5);
insert into tb_access values('A','2018-03',16);
insert into tb_access values('A','2018-03',22);
insert into tb_access values('B','2018-03',23);
insert into tb_access values('B','2018-03',10);
insert into tb_access values('B','2018-03',1);
commit;
--创建临时表存放当月访问次数
--首先创建表(当where条件为否时只创建表)
create table tb_access_mon
as
select t.name
, t.mon
, sum(t.num) mon_sum
from tb_access t
where 1=2
group by t.name,t.mon;
--插入数据
insert into tb_access_mon
select t.name
, t.mon
, sum(t.num)
from tb_access t
where 1=1
group by t.name,t.mon
order by 1,2;
commit;
--查询tb_access_mon
select * from tb_access_mon;
NAME MON SUM(T.NUM)
A 2018-03 38
A 2018-02 10
A 2018-01 33
B 2018-03 34
B 2018-02 15
B 2018-01 30
方法一:(仅适用于oracle数据库)
--使用开窗函数计算累计的值
select name
, mon
, mon_sum
, sum(mon_sum) over(partition by name order by mon) mon_sum_t
from tb_access_mon;
ANAME AMON AMON_SUM MON_SUM
A 2018-01 33 33
A 2018-02 10 43
A 2018-03 38 81
B 2018-01 30 30
B 2018-02 15 45
B 2018-03 34 79
方法二:使用join的方法
--创建表
create table tb_access_mon_view
as
select a.name as aname
, a.mon as amon
, a.mon_sum as amon_sum
, b.name
, b.mon as bmon
, b.mon_sum as bmon_sum
from tb_access_mon a
join tb_access_mon b
on a.name = b.name
where 1=2;
--插入数据
insert into tb_access_mon_view
select a.name as aname
, a.mon as amon
, a.mon_sum as amon_sum
, b.name
, b.mon as bmon
, b.mon_sum as bmon_sum
from tb_access_mon a
join tb_access_mon b
on a.name = b.name
where 1=1;
--查询新建的表tb_access_mon_view
select * from tb_access_mon_view;
ANAME AMON AMON_SUM NAME BMON BMON_SUM
A 2018-03 38 A 2018-01 33
A 2018-02 10 A 2018-01 33
A 2018-01 33 A 2018-01 33
A 2018-03 38 A 2018-02 10
A 2018-02 10 A 2018-02 10
A 2018-01 33 A 2018-02 10
A 2018-03 38 A 2018-03 38
A 2018-02 10 A 2018-03 38
A 2018-01 33 A 2018-03 38
B 2018-03 34 B 2018-01 30
B 2018-02 15 B 2018-01 30
B 2018-01 30 B 2018-01 30
B 2018-03 34 B 2018-02 15
B 2018-02 15 B 2018-02 15
B 2018-01 30 B 2018-02 15
B 2018-03 34 B 2018-03 34
B 2018-02 15 B 2018-03 34
B 2018-01 30 B 2018-03 34
最后的原理是把每一行对应比那个月份的值小于等于的分成一组;
--查询单月访问次数和总访问次数
select aname
, amon
, amon_sum
, sum(bmon_sum) mon_sum
from tb_access_mon_view
where amon >= bmon
group by aname,amon,amon_sum
order by aname,amon;
ANAME AMON AMON_SUM MON_SUM
A 2018-01 33 33
A 2018-02 10 43
A 2018-03 38 81
B 2018-01 30 30
B 2018-02 15 45
B 2018-03 34 79
注:
但这有个弊端,如果数据多的话,这样的连接相当于笛卡尔积,有可能内存并不能放下这么多的数据,造成这样的方法会报错