hive按日期连续统计每天的新增和总量

记录一次统计需求的实现:

需求:

现有表ticket_detail(telphone,name,createddate),记录了人员新增信息,每增加一行,代表有新的人员加入。表ticket_detail示例如下:
hive按日期连续统计每天的新增和总量_第1张图片
现在要统计每天新增的人数,以及每天新增后的人员总数,并且,要去重相同的人员,通过(telphone,name)来唯一标识一个人员。

统计结果

先看统计后的结果:
hive按日期连续统计每天的新增和总量_第2张图片

实现方法

接下来是阐述实现方法。数据库类型为hive。

(1)第一步,先要实现去重
#选择数据库
use test;

#创建一个新表
create table if not exists people(
telphone string,
name string,
createddate string,
flag int)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS textfile;

#往表内插入数据
insert overwrite table people
SELECT  
telphone AS telphone, name AS name, TO_DATE(createddate) AS createddate, 
ROW_NUMBER() OVER(PARTITION BY telphone, name ORDER BY TO_DATE(createddate) ASC) AS flag 
FROM ticket_detail

说明:
(1)TO_DATE(xxxx),能将string格式的“2019-03-25 10:44:25.0”转变为“2019-03-25”;
(2)ROW_NUMBER() OVER(PARTITION BY telphone, name ORDER BY TO_DATE(createddate) ASC),可以生成排序号码,现根据telphone, name来分组,再根据TO_DATE(createddate) 来排序。这个的目的是为了找出相同的(telphone, name)

代码运行之后,得到表people:
hive按日期连续统计每天的新增和总量_第3张图片
可以看到,相同的(telphone,name)二元组被找出来了,并且根据时间来排序。

这样的做法的好处是,当我们限定where flag=1时,就能实现去重效果,并且留下的记录时日期最高的记录。

(2)第二步,统计数目
#选择数据库
use test;

#创建一个新表
create table if not exists people_count(
datetime string,
num int,
total int)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS textfile;

#插入数据
insert overwrite table people_count
SELECT a.createddate , a.num , SUM(b.num) as total FROM
(select createddate  ,count(1) as num from mid_yyts_people where flag=1 group by createddate)  a
,
(select createddate  ,count(1) as num from mid_yyts_people where flag=1 group by createddate)  b
where a.createddate >= b.createddate  GROUP BY a.createddate , a.num ;

这里用的是笛卡尔积的方式来连接,连接两个相同的查询,并通过a.createddate >= b.createddate来控制求和的日期范围。

其实笛卡尔积的连接的效率不高,会出现n*n的计算,所以本来是打算采用a join b on a.createddate >= b.createddate的连接方式,但是在hive里不允许不等值连接,这种写法只能用在mysql或其他中,所以只能这样a,b这样写

代码运行之后,就能得到我们想要的表people_count:
hive按日期连续统计每天的新增和总量_第4张图片
(该图和上面一样的)
num为每天新增的人员数,total是该天之前所有的人员的总数。

你可能感兴趣的:(hive)