step1:在对用户分层之前,先提取出分层所需的条件(1&2&3&4) -- 1、统计所有日期的最大值 -- 2、统计每位用户的最后活跃日期 -- 3、统计每位用户的最初活跃日期 -- 4、统计“今天”日期("今天":以所有用户为基础,统计所有人中最后活跃的日期;进行子查询的原因:如果直接取数,那么取出的就只是“不同用户的最后活跃日期”,而非“所有用户的最后活跃日期”————基准不一样) with time as( select uid, date(max(in_time)) as last_day, date(min(in_time)) as first_day, (select date(max(in_time)) from tb_user_log) as today from tb_user_log group by 1 ) step3:对用户分级之后,进行比例计算 -- 1、挑选“用户等级”字段 -- 2、计算比例(round保留2位小数) 【分子为何为去重的uid?分母为何从time临时表中取数?:首先,各类用户的比例计算公式=该类用户人数/所有用户人数(所有比例累加=1), 分子为各类用户的人数计数(刚刚分类好的用户+group by=各类用户人数)、 分母为全用户人数(从time临时表中取出的uid计数,为已经去重的uid,即所有用户人数计数) 补充:分母不能直接用t1表进行计数,是因为前1个字段(分组条件)已经固定为“用户等级”】 select t1.user_grade, round(count(distinct t1.uid) / (select count(uid) from time),2) as ratio from( step2:对用户进行分层(补充:datediff函数(终止时间,开始时间),返回二者的“天数”时间差) -- 1、近7天新增【当每位用户的“今天”VS“初次活跃日期”之差<=6天时】,则为“新晋用户”; (新增:新来的即为新增,也就是说只按第1次活跃日期作为判断标准,即“初次活跃日期”) (结合题意可知:判断用户是不是“近7天内”且“首次”观看了视频,7天前首次观看的不算) -- 2、非新晋用户【当每位用户的“今天”VS“初次活跃日期”之差>6天时】且近7天活跃过【当每位用户的“今天”VS“最后活跃日期”之差<=6天时】,则为“忠实用户”; (近7天有活跃,但为非新晋用户:“首次”观看日期不能在7天之内,但还要在7天之内活跃过👉直接拿“last活跃日期”与“今天”作日期差的判断👉原因:即便用户有多条活跃记录,但最后1条活跃记录势必是与“今天”日期最近的(极限思维),只要其符合条件,就算OK) -- 3、《此处有默认条件:非新晋用户》【当每位用户的“今天”VS“初次活跃日期”之差>6天时】更早前活跃过但近7天未活跃【当每位用户的“今天”VS“最后活跃日期”之差>6天时】,则为“沉睡用户”; -- 4、《此处有默认条件:非新晋用户》【当每位用户的“今天”VS“初次活跃日期”之差>6天时】更早前活跃过但近30天未活跃【当每位用户的“今天”VS“最后活跃日期”之差>29天时】,则为“流失用户”。 select uid, case when datediff(today, first_day) <= 6 then '新晋用户' when datediff(today, first_day) > 6 and datediff(today, last_day) <= 6 then '忠实用户' when datediff(today, first_day) > 6 and datediff(today, last_day) > 29 then '流失用户' when datediff(today, first_day) > 6 and datediff(today, last_day) > 6 then '沉睡用户' else '其他' end as user_grade from time) as t1 group by 1 order by 2 desc