题解 | #连续签到领金币#
连续签到领金币
https://www.nowcoder.com/practice/aef5adcef574468c82659e8911bb297f
思路跟大家是一样的,就不放图解啦;唯一好处就是不断嵌套的写法:
1. 很好理解(所有新增列,都源于题目一个表)
2. 没有重复出现的语句
3. 方便一步步检验
SELECT uid,DATE_FORMAT(sign_dt,"%Y%m") month,SUM(coin_cnt) coin FROM ( SELECT uid,sign_dt, #求得某个uid在某天签到时候获得的金币数 CASE WHEN rank_day % 7 = 3 THEN 3 WHEN rank_day % 7 = 0 THEN 7 ELSE 1 END coin_cnt # coin列,表示每次签到增加的金币数 FROM ( SELECT uid,sign_dt,ROW_NUMBER()OVER(PARTITION BY uid,date_group ORDER BY sign_dt) rank_day # 在这个签到周期内排序,求得第几天 FROM ( SELECT uid,sign_dt,DATE_SUB(sign_dt,INTERVAL sign_cnt DAY) date_group # 以这个日期分组;一组一个签到周期 FROM ( SELECT DISTINCT uid, DATE(in_time) sign_dt, #没有group by时,distinct一下保证唯一性 ROW_NUMBER()OVER(PARTITION BY uid ORDER BY DATE(in_time)) sign_cnt FROM tb_user_log WHERE artical_id = 0 AND sign_in = 1 AND DATE(in_time) BETWEEN "2021-07-07" AND "2021-10-31" ) t1 ) t2 ) t3 ) t4 GROUP BY uid, DATE_FORMAT(sign_dt,"%Y%m") ORDER BY month, uid