杨大伟在路上

大数据第50天—Mysql练习题12道之五-活跃用户的总数-杨大伟

有日志如下,请写出代码求得所有用户和活跃用户的总数及平均年龄。(活跃用户指连续两天都有访问记录的用户)

日期 用户 年龄

11,test_1,23

11,test_2,19

11,test_3,39

11,test_1,23

11,test_3,39

11,test_1,23

12,test_2,19

13,test_1,23

 

1 create table test_five_active(
2     active_time string COMMENT '活跃日期',
3     user_id string COMMENT '用户id',
4     age int COMMENT '用户年龄'
5 )
6 row format delimited fields terminated by '\t';
 1 insert into table test_five_active values ('11','test_1',11);
 2 insert into table test_five_active values ('11','test_2',22);
 3 insert into table test_five_active values ('11','test_3',33);
 4 insert into table test_five_active values ('11','test_4',44);
 5 
 6 insert into table test_five_active values ('12','test_3',33);
 7 insert into table test_five_active values ('12','test_5',55);
 8 insert into table test_five_active values ('12','test_6',66);
 9 
10 insert into table test_five_active values ('13','test_4',44);
11 insert into table test_five_active values ('13','test_5',55);
12 insert into table test_five_active values ('13','test_7',77);
 1 -- 所有用户的总数及平均年龄
 2 select
 3     count(*) sum_user,
 4     avg(age) avg_age
 5 from
 6 (
 7     select 
 8         user_id,
 9         avg(age) age
10     from test_five_active
11     group by user_id
12 ) t1;
13 
14 -- 活跃人数的总数及平均年龄
15 select  -- 最外一层算出活跃用户的个数以及平均年龄
16     count(*),
17     avg(d.age)
18 from
19 (
20     select -- 最后还需要以user_id分组,去重(防止某个用户在11,12号连续活跃,然后在14,15号又连续活跃,导致diff求出不一致,所以此用户会出现两次)
21         c.user_id,
22         c.age
23     from
24     (
25         select -- 以用户和差值diff分组,看分组下的数据的个数是否大于等于2(连续两天登录),取出活跃用户的数据
26             b.user_id,
27             b.age,
28             b.diff,
29             count(*) flag
30         from
31         (
32             select  -- 用活跃日期减去排名,求出差值,看差值是否相等,相等差值的数据肯定是连续活跃的数据
33                 a.active_time,
34                 a.user_id,
35                 a.age,
36                 a.rank_time,
37                 a.active_time-a.rank_time diff 
38             from
39             (
40                 select  -- 以用户和活跃日期分组(去重,防止某个用户在同一天活跃多次),求出每个用户的活跃日期排名
41                     active_time,
42                     user_id,
43                     age,
44                     rank() over(partition by user_id order by active_time) rank_time
45 
46                 from test_five_active
47                 group by active_time,user_id,age   
48             ) a
49         ) b
50         group by b.user_id,b.age,b.diff
51         having count(*) >=2
52     ) c
53     group by c.user_id,c.age
54 ) d;

 

posted on 2020-08-31 20:09  浪子逆行  阅读(443)  评论(0编辑  收藏  举报

导航