明确题意:
统计每个6/7级用户总活跃月份数、2021年活跃天数、2021年试卷作答活跃天数、2021年答题活跃天数,按照总活跃月份数、2021年活跃天数降序排序。
问题拆解:
- 本题主要是考察知识点:join、case when 、group by、date_format等
- DATE_FORMAT(submit_time, "%Y-%m-%d" ) 返回的是2021-09-01这样;
- 先查出level=6,7的用户,得到表t1
- t2,t3,t4,t5分别对应用户总活跃月份数、2021年活跃天数、2021年试卷作答活跃天数、2021年答题活跃天数
- 要用left join关联,有些用户没有作答某个题目时,记录也要保留!
- 最后的结果有NULL时需要用case when 处理一下
代码实现:
select t1.uid, case when t2.act_month_total is null then 0 else t2.act_month_total end as act_month_total, case when t3.act_days_2021 is null then 0 else t3.act_days_2021 end as act_days_2021, case when t4.act_days_2021_exam is null then 0 else t4.act_days_2021_exam end as act_days_2021_exam, case when t5.act_days_2021_question is null then 0 else t5.act_days_2021_question end as act_days_2021_question from ( select * from user_info where level in (6,7) )t1 -- join 不能用join left join ( select uid ,count(*) as act_month_total from ( select uid, DATE_FORMAT(act_time , '%Y-%m') from ( select uid,'exam' as type,start_time as act_time from exam_record union all select uid,'practice' as type,submit_time as act_time from practice_record )t00 group by uid, DATE_FORMAT(act_time , '%Y-%m') )t01 group by uid )t2 on t1.uid = t2.uid -- join 不能用join left join ( select uid ,count(*) as act_days_2021 from ( select uid, DATE_FORMAT(act_time , '%Y-%m-%d') from ( select uid,'exam' as type,start_time as act_time from exam_record union all select uid,'practice' as type,submit_time as act_time from practice_record )t00 where year(act_time) = '2021' group by uid, DATE_FORMAT(act_time , '%Y-%m-%d') )t01 group by uid )t3 on t1.uid = t3.uid -- join 不能用join left join ( select uid ,count(*) as act_days_2021_exam from ( select uid, DATE_FORMAT(act_time , '%Y-%m-%d') from ( select uid,'exam' as type,start_time as act_time from exam_record )t00 where year(act_time) = '2021' group by uid, DATE_FORMAT(act_time , '%Y-%m-%d') )t01 group by uid )t4 on t1.uid = t4.uid -- join 不能用join left join ( select uid ,count(*) as act_days_2021_question from ( select uid, DATE_FORMAT(act_time , '%Y-%m-%d') from ( select uid,'practice' as type,submit_time as act_time from practice_record )t00 where year(act_time) = '2021' group by uid, DATE_FORMAT(act_time , '%Y-%m-%d') )t01 group by uid )t5 on t1.uid = t5.uid order by t2.act_month_total desc , t3.act_days_2021 desc ;
为啥不能用join?如下,t2不含有1003,但1003的记录要保留下来,算作是0!!!
mysql> select uid ,count(*) as act_month_total -> from ( -> select -> uid, DATE_FORMAT(act_time , '%Y-%m-%d') -> from ( -> select uid,'exam' as type,start_time as act_time -> from exam_record -> union all -> select uid,'practice' as type,submit_time as act_time -> from practice_record -> )t00 -> group by uid, DATE_FORMAT(act_time , '%Y-%m-%d') -> )t01 group by uid -> ; +------+-----------------+ | uid | act_month_total | +------+-----------------+ | 1001 | 2 | | 1005 | 1 | | 1006 | 5 | | 1002 | 1 | | 1004 | 1 | +------+-----------------+ 5 rows in set (0.00 sec)
不足之处,欢迎指正。