• 数据仓库 用户留存主题


    需求:计算前1天,2天,3天的用户留存数量和用户留存率。

    用户留存:某段时间内的新增用户,经过一段时间后,仍然使用应用的被认作是留存用户;这部分用户占当时新增用户的比例即是留存率。例如,5月份新增用户200,这200人在6月份启动过应用的有100人,7月份启动过应用的有80人,8月份启动过应用的有50人;则5月份新增用户一个月后的留存率是50%,二个月后的留存率是40%,三个月后的留存率是25%。

    实现思路:例如,要计算2019-02-11的1日留存用户,需要知道两种数据,一是2019-02-10新增了哪些用户(在每日新增设备明细表中),二是2019-02-11的活跃用户有哪些(在每日活用户表中)。如果一个用户既是2019-02-10的新增用户,又是2019-02-11的活跃用户,此用户即为2019-02-10的1日留存用户。

    数据来源:DWS层的日活表和新增设备明细表。

    DWS层(每日留存用户明细表)

    建表语句。

    分析:

    ①此表采用了分区表的形式,以每天的日期为分区。因为每天都有自己的1日留存,2日留存,3日留存。。。等情况,数据量相对较大。但因为都是针对新增设备的留存明细,数据量只能说相对较大,并没有达到非用分区表不可的地步。

    ②表中有两个重要的字段,设备新增时间和直到今日的留存天数。例如,在2010-02-11那天,数据可能出现设备新增日期为2019-02-10,留存天数为1的数据;设备新增日期为2019-02-09,留存天数为2的数据。。。等等。

    ③DWS层还只是一个留存明细表,具体有多少留存,还需要去ADS做count操作。

    drop table if exists dws_user_retention_day;
    create external table dws_user_retention_day 
    (
        `mid_id` string COMMENT '设备唯一标识',
        `user_id` string COMMENT '用户标识', 
        `version_code` string COMMENT '程序版本号', 
        `version_name` string COMMENT '程序版本名', 
      `lang` string COMMENT '系统语言', 
      `source` string COMMENT '渠道号', 
      `os` string COMMENT '安卓系统版本', 
      `area` string COMMENT '区域', 
      `model` string COMMENT '手机型号', 
      `brand` string COMMENT '手机品牌', 
      `sdk_version` string COMMENT 'sdkVersion', 
      `gmail` string COMMENT 'gmail', 
      `height_width` string COMMENT '屏幕宽高',
      `app_time` string COMMENT '客户端日志产生时的时间',
      `network` string COMMENT '网络模式',
      `lng` string COMMENT '经度',
      `lat` string COMMENT '纬度',
       `create_date`    string  comment '设备新增时间',
       `retention_day`  int comment '截止当前日期留存天数'
    )  COMMENT '每日用户留存情况'
    PARTITIONED BY (`dt` string)
    stored as parquet
    location '/warehouse/gmall/dws/dws_user_retention_day/'

    数据导入,以2019-02-11的1日,2日,3日留存为例

    分析:

    ①在sql中,用户活跃日期固定为统计日期(2019-02-11),而设备新增日期随着留存天数retention_day 不同,在统计日期(2019-02-11)上减去相应的天数。

    ②将所有的sql结果进行union all,就得到了2019-02-11相对于2019-02-10的1日留存,相对于2019-02-09的2日留存和相对于2019-02-08的3日留存。若要计算其他留存天数,进行类似重复操作即可。

    insert overwrite table dws_user_retention_day
    partition(dt="2019-02-11")
    select
        nm.mid_id,
        nm.user_id,
        nm.version_code,
        nm.version_name,
        nm.lang,
        nm.source,
        nm.os,
        nm.area,
        nm.model,
        nm.brand,
        nm.sdk_version,
        nm.gmail,
        nm.height_width,
        nm.app_time,
        nm.network,
        nm.lng,
        nm.lat,
        nm.create_date,
        1 retention_day 
    from dws_uv_detail_day ud join dws_new_mid_day nm  on ud.mid_id =nm.mid_id 
    where ud.dt='2019-02-11' and nm.create_date=date_add('2019-02-11',-1)
    
    union all
    select  
        nm.mid_id,
        nm.user_id , 
        nm.version_code , 
        nm.version_name , 
        nm.lang , 
        nm.source, 
        nm.os, 
        nm.area, 
        nm.model, 
        nm.brand, 
        nm.sdk_version, 
        nm.gmail, 
        nm.height_width,
        nm.app_time,
        nm.network,
        nm.lng,
        nm.lat,
        nm.create_date,
        2 retention_day 
    from  dws_uv_detail_day ud join dws_new_mid_day nm   on ud.mid_id =nm.mid_id 
    where ud.dt='2019-02-11' and nm.create_date=date_add('2019-02-11',-2)
    
    union all
    select  
        nm.mid_id,
        nm.user_id , 
        nm.version_code , 
        nm.version_name , 
        nm.lang , 
        nm.source, 
        nm.os, 
        nm.area, 
        nm.model, 
        nm.brand, 
        nm.sdk_version, 
        nm.gmail, 
        nm.height_width,
        nm.app_time,
        nm.network,
        nm.lng,
        nm.lat,
        nm.create_date,
        3 retention_day 
    from  dws_uv_detail_day ud join dws_new_mid_day nm   on ud.mid_id =nm.mid_id 
    where ud.dt='2019-02-11' and nm.create_date=date_add('2019-02-11',-3);

    ADS层留存用户数和留存用户比率

    建表语句

    分析:注意,此表既包括留存数量,也包括用户留存比率(某日的n天留存,有2个条件)

    drop table if exists ads_user_retention_day_rate;
    create external table ads_user_retention_day_rate 
    (
         `stat_date`          string comment '统计日期',
         `create_date`       string  comment '设备新增日期',
         `retention_day`     int comment '截止当前日期留存天数',
         `retention_count`    bigint comment  '留存数量',
         `new_mid_count`     bigint comment '当日设备新增数量',
         `retention_ratio`   decimal(10,2) comment '留存率'
    )  COMMENT '每日用户留存情况'
    row format delimited fields terminated by '	'
    location '/warehouse/gmall/ads/ads_user_retention_day_rate/';

    导入数据。

    ①数据来源于上一张用户每日留存明细表。

    ②where条件dt='2019-02-11',说明要拿出每日留存明细表中2019-02-11的所有数据(不同留存天数)。

    ②group by create_date,retention_day,分组条件有2个,其实只用一个条件分组也可以,但是select的字段必须是分组字段,或者在聚合函数里,为了方便,用这两个条件分组,且不影响结果。

    ③留存率 = 留存用户数 / 当天新增用户总数。所以需要 join ADS层的ads_new_mid_count ,里面保存了每日新增的用户(设备)数量。

    insert into table ads_user_retention_day_rate
    select 
        '2019-02-11', 
        ur.create_date,
        ur.retention_day, 
        ur.retention_count, 
        nc.new_mid_count,
        ur.retention_count/nc.new_mid_count*100
    from 
    (
        select
            create_date,
            retention_day,
            count(*) retention_count
        from dws_user_retention_day
        where dt='2019-02-11' 
        group by create_date,retention_day
    ) ur join ads_new_mid_count nc on nc.create_date=ur.create_date;
  • 相关阅读:
    快速排序?
    算法和数据结构?
    渲染一个react?
    移动端兼容适配?
    PWA全称Progressive Web App,即渐进式WEB应用?
    InnoDB一棵B+树可以存放多少行数据?
    移动端首屏优化?
    InnoDB什么时候会锁表?
    数组去重,多种方法?
    如何处理异形屏iphone X?
  • 原文地址:https://www.cnblogs.com/noyouth/p/13196676.html
Copyright © 2020-2023  润新知