一、问题拆解:
①数据底表tb1,是20210707-20211031,artical_id=0,sign_in=1的数据;
②7天一个周期,需要将周期进行编号,便于后续分组计算,方法是((某日期-最早日期)/7+1)取整作为周期数;
③是否连续3天、连续7天签到判断,用窗口函数+窗口范围range interval n day preceding来实现。
二、解答步骤:
①先把数据底表tb1取好;
②根据tb1计算cycle,形成tb2;
③窗口函数sum根据uid、cycle进行分组,计算3天内、7天内移动累加值,形成tb3;
④判断:每个uid,月份,cycel分组内3天、7天移动累加值是否等于3和7,如果等于则表明可以获得额外的2分和6分,此时形成tb4;
⑤在tb4基础上进行最终取值和计算即可。

with tb1 as(
select uid, date(in_time) as sign_day, sign_in
from tb_user_log 
where artical_id=0 and sign_in=1 and date(in_time) between '2021-07-07' and '2021-10-31'
group by uid, date(in_time))

select uid, `month`, sum(coin)
from(
select uid, date_format(sign_day,'%Y%m') as `month`,
case when max(sign_num_3d)=3 and max(sign_num_7d)=7 then max(sign_num_7d)+8
when max(sign_num_3d)=3 and max(sign_num_7d)<7 then max(sign_num_7d)+2
else max(sign_num_7d) end as coin
from(
select uid, sign_day, cycle,
sum(sign_in)over(partition by cycle,uid order by sign_day range interval 2 day preceding) as sign_num_3d,
sum(sign_in)over(partition by cycle,uid order by sign_day range interval 6 day preceding) as sign_num_7d
from(
select uid, sign_day, 
floor(datediff(sign_day,min(sign_day)over(partition by uid))/7+1) cycle, 
sign_in
from tb1) as tb2
) as tb3
group by uid, `month`, cycle) as tb4
group by uid, `month`
order by uid, `month`