sql面试题 连续签到领金币(连续登录问题)

牛客面试题

  • 问题:计算每个用户2021年7月以来每月获得的金币数

问题一:连续登录问题

    select uid,date(in_time) as dt,
    row_number() over(partition by uid order by date(in_time)) 编号,
	date(in_time)-(row_number() over(partition by uid order by date(in_time))) dt2
	from tb_user_log
	where date(in_time) between '2021-07-07' and '2021-10-31'
					and artical_id=0 and sign_in=1

sql面试题 连续签到领金币(连续登录问题)_第1张图片

  1. 利用每个登录日期减去生成的编号会得到一个数值,可知:如果数值一样,则相同的数值的行数记为连续登录天数。

连续登录天数满3得3,满7得7.

select *,row_number() over(partition by uid,dt2 order by dt) 连续登录天数,
		case
		when row_number() over(partition by uid,dt2 order by dt)%7=3 then 3
        when row_number() over(partition by uid,dt2 order by dt)%7=0 then 7
        else 1 end as 金币
        
from ( 	  --  生成编号,利用每个登陆日期减去编号得到一个数值,可利用该数值得到连续登录天数
    select uid,date(in_time) as dt,
    row_number() over(partition by uid order by date(in_time)) 编号,
	date(in_time)-(row_number() over(partition by uid order by date(in_time))) dt2
	from tb_user_log
	where date(in_time) between '2021-07-07' and '2021-10-31'
					and artical_id=0 and sign_in=1
)t

sql面试题 连续签到领金币(连续登录问题)_第2张图片

  • 利用 连续登录天数 % 7 =3 输出3
  • 连续登录天数 %7 =7 输出7 ,否则输出1.
  • 连续登录天数的开窗函数(错误点)
  • row_number() over(partition by uid,dt2 order by dt) 连续登录天数

完整代码

select uid,date_format(dt,"%Y%m") month,
	sum(金币) coin
from( -- 根据得到的数值,可知一旦数值不一样说明登录天数不连续。进而判断得到的每天得到的金币
select *,row_number() over(partition by uid,dt2 order by dt) 连续登录天数,
		case
		when row_number() over(partition by uid,dt2 order by dt)%7=3 then 3
        when row_number() over(partition by uid,dt2 order by dt)%7=0 then 7
        else 1 end as 金币
        
from ( 	  --  生成编号,利用每个登陆日期减去编号得到一个数值,可利用该数值得到连续登录天数
    select uid,date(in_time) as dt,
    row_number() over(partition by uid order by date(in_time)) 编号,
	date(in_time)-(row_number() over(partition by uid order by date(in_time))) dt2
	from tb_user_log
	where date(in_time) between '2021-07-07' and '2021-10-31'
					and artical_id=0 and sign_in=1
)t
)tt
group by uid,month
order by uid,month ;

你可能感兴趣的:(mysql,sql,数据库)