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

连续签到领金币

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

打标签法

(为了详述标记过程,用层层子查询描述。)

第一层:

select distinct uid,
            date(in_time) as date,     
			#签到日期去重
			row_number() over(partition by uid order by date(in_time) asc) as uid_rk,    
			#分别为每个人的签到日期排名
            date(in_time)-row_number() over(partition by uid order by date(in_time) asc) as date_group  #日期减去排名数得到相同数字的即为连续签到
            from tb_user_log
            where artical_id =0
			and sign_in=1
            and date(in_time) between '2021-07-07' and '2021-10-31' 

第一层标签如图:

第二层:

select *,
        row_number() over(partition by date_group,uid order by date asc) as group_rk
		#在每个连续签到组中再进行排序,方便后续计算
        from 
            (select distinct uid,
            date(in_time) as date,
			row_number() over(partition by uid order by date(in_time) asc) as uid_rk,
            date(in_time)-row_number() over(partition by uid order by date(in_time) asc) as date_group
            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

第三层:

select *,
    date_format(date,'%Y%m') as month,
	#给每次签到打上月份标签
    case group_rk%7
        when 3 then 3
        when 0 then 7
        else 1 end as day_coin
	#组中排名对7取余数,决定其领得金币数
    from 
        (select *,
        row_number() over(partition by date_group,uid order by date asc) as group_rk
        from 
            (select distinct uid,
            date(in_time) as date,
			row_number() over(partition by uid order by date(in_time) asc) as uid_rk,
            date(in_time)-row_number() over(partition by uid order by date(in_time) asc) as date_group
            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

最后代码:

select uid,
month,
sum(day_coin) as coin
#根据ID,月份聚合后,对分数求和即可得出每人每月金币总数
from 
    (select *,
    date_format(date,'%Y%m') as month,
    case group_rk%7
        when 3 then 3
        when 0 then 7
        else 1 end as day_coin
    from 
        (select *,
        row_number() over(partition by date_group,uid order by date asc) as group_rk
        from 
            (select distinct uid,
            date(in_time) as date,
			row_number() over(partition by uid order by date(in_time) asc) as uid_rk,
            date(in_time)-row_number() over(partition by uid order by date(in_time) asc) as date_group
            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
group by uid,month
order by month asc,uid asc

全部评论

相关推荐

01-30 09:45
燕山大学 Java
喵_coding:这种直接跑就完事了 哪有毕业了才签合同 任何offer和三方都没有的
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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