代码

  
  select 
	tb.min_in_time dt,
	round(sum(if(datediff(tb.uv_time,tb.min_in_time)=1,1,0))/count(distinct uid),2) uv_left_rate
    -- count(distinct uid) 每天活跃的用户总数量
    -- sum(if(datediff(tb.uv_time,tb.min_in_time)=1,1,0))第一天新增用户且第二天活跃的人,就计数,累计求和得到点当天新增且第二天又活跃的用户数
  from (
		 select a.uid,min_in_time,uv_time -- 每个用户最早进入时间以及所有活跃的时间
		  from 
		  ( -- 用户活跃所有活跃时间,这里UNION主要是因为如果in_time-进入时间和out_time-离开时间跨天了,在两天里都记为该用户活跃过
			   select uid,date(in_time) uv_time
			  from tb_user_log ul
			  union 
			  select uid,date(out_time) uv_time
			  from tb_user_log ul
		  )a
		  join 
		  ( -- 用户最早活跃时间
			  select uid,min(date(in_time)) min_in_time
			  from tb_user_log ul
			  group by uid
		  )b
		  on a.uid=b.uid
  ) tb
  group by min_in_time -- 按最早进入时间进行分组,若当天无新用户自然也不用输出
  having year(dt)=2021 and month(dt)=11 -- 2021年11月的用户
  order by dt -- 升序