题解 | #每个6/7级用户活跃情况#
每个6/7级用户活跃情况
https://www.nowcoder.com/practice/a32c7c8590324c96950417c57fa6ecd1
这道题我的想法是先把主键uid的条件筛选放一边,分别用四个子查询获得四个列,然后基于主键齐全表(就是user_info)连接四个列,最后再筛选uid
这四个列中,前两个逻辑相似,以下
select uid,count(distinct st) act_month_total from (select uid,substr(submit_time,1,7) st from exam_record union select uid,substr(submit_time,1,7) st from practice_record) t1 group by uid
select uid,count(distinct st) act_days_2021 from (select uid,substr(submit_time,1,10) st,year(submit_time) yy from exam_record union select uid,substr(submit_time,1,10) st,year(submit_time) yy from practice_record) t2 where t2.yy=2021 group by uid
后两个也是逻辑相似且更简单
select uid,count(distinct st) act_days_2021_exam from (select uid,substr(submit_time,1,10) st,year(submit_time) yy from exam_record ) t3 where t3.yy=2021 group by uid
select uid,count(distinct st) act_days_2021_question from (select uid,substr(submit_time,1,10) st,year(submit_time) yy from practice_record ) t4 where t4.yy=2021 group by uid
接下来用user_info表左连接它们(为了保证所有uid都查到)
select ui.uid, ifnull(act_month_total,0) act_month_total, ifnull(act_days_2021,0) act_days_2021, ifnull(act_days_2021_exam,0) act_days_2021_exam, ifnull(act_days_2021_question,0) act_days_2021_question from user_info ui left join (select uid,count(distinct st) act_month_total from (select uid,substr(submit_time,1,7) st from exam_record union select uid,substr(submit_time,1,7) st from practice_record) t1 group by uid) T1 on ui.uid=T1.uid left join (select uid,count(distinct st) act_days_2021 from (select uid,substr(submit_time,1,10) st,year(submit_time) yy from exam_record union select uid,substr(submit_time,1,10) st,year(submit_time) yy from practice_record) t2 where t2.yy=2021 group by uid) T2 on ui.uid=T2.uid left join (select uid,count(distinct st) act_days_2021_exam from (select uid,substr(submit_time,1,10) st,year(submit_time) yy from exam_record ) t3 where t3.yy=2021 group by uid) T3 on ui.uid=T3.uid left join (select uid,count(distinct st) act_days_2021_question from (select uid,substr(submit_time,1,10) st,year(submit_time) yy from practice_record ) t4
最后再加上Uid的筛选即可
select ui.uid, ifnull(act_month_total,0) act_month_total, ifnull(act_days_2021,0) act_days_2021, ifnull(act_days_2021_exam,0) act_days_2021_exam, ifnull(act_days_2021_question,0) act_days_2021_question from user_info ui left join (select uid,count(distinct st) act_month_total from (select uid,substr(submit_time,1,7) st from exam_record union select uid,substr(submit_time,1,7) st from practice_record) t1 group by uid) T1 on ui.uid=T1.uid left join (select uid,count(distinct st) act_days_2021 from (select uid,substr(submit_time,1,10) st,year(submit_time) yy from exam_record union select uid,substr(submit_time,1,10) st,year(submit_time) yy from practice_record) t2 where t2.yy=2021 group by uid) T2 on ui.uid=T2.uid left join (select uid,count(distinct st) act_days_2021_exam from (select uid,substr(submit_time,1,10) st,year(submit_time) yy from exam_record ) t3 where t3.yy=2021 group by uid) T3 on ui.uid=T3.uid left join (select uid,count(distinct st) act_days_2021_question from (select uid,substr(submit_time,1,10) st,year(submit_time) yy from practice_record ) t4 where t4.yy=2021 group by uid) T4 on ui.uid=T4.uid where ui.uid in (select uid from user_info where level=6 or level=7) order by act_month_total desc, act_days_2021 desc
这样一来就把问题拆解完成了
或许不是最简单优雅的方法,也或许很多人和我想得差不多,但感觉还是思路很清晰哒