select 
    round(
        sum(case when temp2.device_id is not null then 1 else 0    end) / count(temp1.device_id),4)
         as avg_ret
from
    (select distinct device_id,date 
     from question_practice_detail) temp1
     left join
    (select distinct device_id,date 
     from question_practice_detail) temp2
     on temp1.device_id = temp2.device_id 
     and temp2.date = temp1.date + 1

1.弄清什么是次日留存率,找准所需数据

次日留存率 = 次日登录的用户数量 / 当日用户的注册数量

所以需要时间和总数

关于时间,次日 = 当日 + 1

关于数量,因为每个用户在一天可重复登陆,所以要distinct去重,直接count计数;而次日用户可能登陆可能不登陆,所以不能直接count计数,用sum函数加case语句计算次日登陆数量

2.因为要取当日数据和次日数据,分别先把数据取出成表(注意命名)再合并(注意合并的方式和条件)

关于合并,由于次日用户是否登录未知,可能存在null值,所以用当日数据表temp1左连接次日数据表进行合并

关于合并条件

  1. 次日date = 当日date + 1
  2. 用户为一一映射关系即当日device_id= 次日device_id

3.注意用round函数保留小数