题解 | #连续签到领金币#

连续签到领金币

https://www.nowcoder.com/practice/aef5adcef574468c82659e8911bb297f

步骤1:获取在指定时间段内以及artical_id为0的登录时间+签到表

with t1 as (
    select 
        uid
        ,date(in_time) as dt
        ,sign_in
    from tb_user_log
    where date(in_time) >= '2021-07-07' and date(in_time) <= '2021-10-31'
    and artical_id = 0
)

步骤2:用窗口函数技巧获取连续签到日

, t2 as (
    select 
        uid
        ,date_format(dt, '%Y%m') as month
        ,dt
        ,date_sub(dt, interval row_number() over(partition by uid order by dt) day) as continue_date
    from t1
    where sign_in = 1  --指定只记录签到日
)

步骤3:使用窗口函数得到当前签到日是连续签到的第几天,然后按照连续登陆的天数,记录每天的金币数

, t3 as (
    select 
        uid
        ,month
        ,case row_number() over(partition by uid, continue_date order by dt)%7 
              when 3 then 3
              when 0 then 7
              else 1
        end as daily_coin
    from t2
)

步骤4:对连续签到日的每日签到得到的金币数求和

select 
    uid
    ,month
    ,sum(daily_coin) as coin
from t3
group by uid, month  
order by month, uid asc;

全体代码:

# 获取签到+登录表
with t1 as (
    select 
        uid
        ,date(in_time) as dt
        ,sign_in
    from tb_user_log
    where date(in_time) >= '2021-07-07' and date(in_time) <= '2021-10-31'
    and artical_id = 0
)
# 获取连续签到日
, t2 as (
    select 
        uid
        ,date_format(dt, '%Y%m') as month
        ,dt
        ,date_sub(dt, interval row_number() over(partition by uid order by dt) day) as continue_date
    from t1
    where sign_in = 1
)
, t3 as (
    select 
        uid
        ,month
        ,case row_number() over(partition by uid, continue_date order by dt)%7 
              when 3 then 3
              when 0 then 7
              else 1
        end as daily_coin
    from t2
)

select 
    uid
    ,month
    ,sum(daily_coin) as coin
from t3
group by uid, month  
order by month, uid asc;

全部评论

相关推荐

04-27 08:59
常州大学 Java
牛客139242382号:《两门以上汇编语言》
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务