一、问题拆解:①活跃天数界定,进出时间跨天当作两天活跃;②判断是否新增用户;③判断是否次日留存。
二、解决步骤:
①活跃天数界定:因为跨天也算活跃,所以把out_time通过union跟in_time联立到一列,记为活跃日期active_day;
②新增用户if_new:该uid所有活跃日期里最小的一天,将该日期编号1否则为0,用窗口函数min配合if进行编号;
③次日留存if_lastday:即当日活跃,当日+1也活跃即为次日留存,将该日期编号1否则为0,则用窗口函数lead配合if进行编号;
④筛选与计算:
  筛选条件:(1)2021年11月(时间筛选放在计算层,在计算之前的子查询里筛会导致11月以前的数据缺失,这样11月的老
  用户会误认为新用户);(2)新增用户数据,即新增用户列的编号为1。
  计算结果:根据日期分组,计算(if_new、if_lastday同时为1的人数)/(if_new为1的人数)即可。

select active_day as dt, 
round(sum(if(if_new=1 and if_lastday=1,1,0))/sum(if_new),2) as uv_left_rate
from(
#用窗口函数+if对是否新增、是否次日留存进行编号,是为1、不是为0
select uid, active_day, 
if(min(active_day)over(partition by uid)=active_day,1,0) as if_new,
if(lead(active_day,1)over(partition by uid order by active_day)=date_add(active_day,interval 1 day),1,0) as if_lastday 
from(
#in和out联立,均当作活跃日期
select uid, date(in_time) as active_day from tb_user_log
union all
select uid, date(out_time) as active_day from tb_user_log
) as tb1
group by uid, active_day
) as tb2
where if_new=1 and date_format(active_day,'%Y%m')='202111'
group by dt
order by dt