一、思路:其实比较清晰,就是每个用户最早min、最晚max活跃时间与T、T-6、T-29之间的关系来划分。用case when分组即可。 二、步骤: 1、先把intime\outtime通过union联立, 2、再用窗口函数min和max提出每个用户最早、最晚活跃时间,用窗口函数count计算总用户数, 3、用case when划分组别, 4、根据用户组别分组、计算。 with tb1 as( select uid, in_time as active_day from tb_user_log union all select uid, out_time as active_day from tb_user_log) select user_grade, round(count(user_grade)/max(total_num),2) as ratio from( select case when min_d<date_sub(T,interval 6 day) and max_d>=date_sub(T,interval 6 day) then '忠实用户' when min_d between date_sub(T,interval 6 day) and T then '新晋用户' when max_d>=date_sub(T,interval 29 day) and max_d<date_sub(T,interval 6 day) then '沉睡用户' when max_d<date_sub(T,interval 29 day) then '流失用户' end as user_grade, count(uid)over() as total_num from( select distinct uid, '20211104' as T, date(min(active_day)over(partition by uid)) as min_d, date(max(active_day)over(partition by uid)) as max_d from tb1 ) as tb2 ) as tb3 group by user_grade order by user_grade, ratio desc