select uid,date_format(t,'%Y%m') as month,
sum(case rn%7 when 3 then 3 when 0 then 7 else 1 end) as coin
from(select uid,t,dt,row_number() over(partition by uid,dt order by t) rn
from(select *,date_add(t,interval - row_number() over(partition by uid order by t) day) as dt
from(select distinct uid,date(in_time) as t,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'
)a
)b
)c group by 1,2 order by 2,1
记忆点
- date_format(time,'%Y%m') 调整time格式,显示结果为年月,如202105
- rn%7 除余计算,显示结果为余数,如8%7结果为1
- row_number() over(partition by uid,dt order by t) rn 窗口函数,无需group by,表示按照uid和dt分组后,按照t升序排序的序号(1,2,3...)无重复
- date_add(time,interval 11 day) 在time基础上增加11天
思路(样例见表格)
- 用日期减去窗口排序,来判断,是否连续签到(即表格中差值列,相同即为连续签到)
- 用除余来判断第三天/第七天,分配不同金币数量(即表格中最后列,在连续基础上的签到天数)
t | rn_t | t-rn_t | rn_(t-rn_t) |
---|---|---|---|
日期 | 对日期排序 | 差值 | 差值做窗口按日期升序排序 |
2021-08-01 | 1 | 2021-07-31 | 1 |
2021-08-02 | 2 | 2021-07-31 | 2 |
2021-08-03 | 3 | 2021-07-31 | 3 |
2021-08-04 | 4 | 2021-07-31 | 4 |
2021-08-06 | 5 | 2021-08-01 | 1 |
2021-08-07 | 6 | 2021-08-01 | 2 |
2021-08-08 | 7 | 2021-08-01 | 3 |
2021-08-09 | 8 | 2021-08-01 | 4 |
2021-08-10 | 9 | 2021-08-01 | 5 |
2021-08-11 | 10 | 2021-08-01 | 6 |
2021-08-12 | 11 | 2021-08-01 | 7 |
2021-08-13 | 12 | 2021-08-01 | 8 |
2021-08-15 | 13 | 2021-08-02 | 1 |
2021-08-16 | 14 | 2021-08-02 | 2 |