非主流方法——自定义变量
连续签到领金币
http://www.nowcoder.com/practice/aef5adcef574468c82659e8911bb297f
本题主要难点在于如何确定当前天是此次连续签到周期中的第几天,下面是我的思路:
with t as
(select distinct uid,artical_id,date(in_time) date,sign_in
from tb_user_log
where artical_id=0 and sign_in=1 and date(in_time) between date('2021-07-07') and date('2021-10-31')
order by uid,date)
#--1.准备一个中间表,把后面步骤需要的字段找出来,把过滤条件也加在这一步,得出每个用户都有哪些天是成功签到的。
select b.uid,
date_format(b.date,'%Y%m') month,
sum(case when b.rk%7=3 then 3
when b.rk%7=0 then 7
else 1 end) coin
#--4.用casewhen判断rk的值,得出每天应得coin的值,并按月份分组求和。
from
(select a.*,if(a.if_continue=0,@rank:=1,@rank:=@rank+1) rk
#--3.利用if判断是否连续,连续则@rank自增,否则重排,得出当前行是本次连续签到周期中的第几天rk。
from
(select t.*,if(lag(t.date,1) over(partition by t.uid)=date_sub(t.date,interval 1 day),1,0) if_continue
from t) a
#--2.取步骤1中表t的所有列,并追加一个判断是否是连续签到的列if_continue,判断当前行登录日期的上一天,与上一行的日期是否相等,相等则说明是连续的,给if_continue赋值1,否则赋值0。
,(select @rank:=1) para) b
group by b.uid,month
order by month,b.uid