用户每天签到可以领1金币,并可以累计签到天数,连续签到的第3、7天分别可以额外领2和6金币。
每连续签到7天重新累积签到天数。
从用户登录明细表中求出每个用户金币总数,并按照金币总数倒序排序
结果如下:
User_id(用户id) | Sum_coin_cn(金币总数) |
---|---|
101 | 7 |
109 | 3 |
107 | 3 |
102 | 3 |
106 | 2 |
104 | 2 |
103 | 2 |
1010 | 2 |
108 | 1 |
105 | 1 |
思路:求出截至到目前用户连续登录的天数,按照coins=max(登录天数)+sum(if(登录天数%3=0, 2, 0))+sum(if(登录天数%7=0, 6, 0)求取金币总数。
第一步:因用户存在一天多次登录的情况,按照用户和登录日期去重并开窗按照用户分组按照登录日期排序进行排名;
第二步:如果登录日期减去排名(记为连续登录标记)相等,则用户处在连续登录。按照用户、连续登录标记计数求出截至到目前用户连续登录的天数;
第三步:按照用户、连续登录标记和公式coins=max(登录天数)+sum(if(登录天数%3=0, 2, 0))+sum(if(登录天数%7=0, 6, 0)求取用户每个连续登录的金币总数。
第四步:求出每个用户的金币总数并排序
-- 求连续并标志是连续的第几天
select
t1.user_id,
t1.login_date,
date_sub(t1.login_date,t1.rk) login_date_rk,
count(*)over(partition by t1.user_id, date_sub(t1.login_date,t1.rk) order by t1.login_date) counti_cn
from
(
select
user_id,
date_format(login_ts,'yyyy-MM-dd') login_date,
rank()over(partition by user_id order by date_format(login_ts,'yyyy-MM-dd')) rk
from
user_login_detail
group by
user_id,date_format(login_ts,'yyyy-MM-dd')
)t1
--求出金币数量,以及签到奖励的金币数量
select
t2.user_id,
max(t2.counti_cn)+sum(if(t2.counti_cn%3=0,2,0))+sum(if(t2.counti_cn%7=0,6,0)) coin_cn
from
(
select
t1.user_id,
t1.login_date,
date_sub(t1.login_date,t1.rk) login_date_rk,
count(*)over(partition by t1.user_id, date_sub(t1.login_date,t1.rk) order by t1.login_date) counti_cn
from
(
select
user_id,
date_format(login_ts,'yyyy-MM-dd') login_date,
rank()over(partition by user_id order by date_format(login_ts,'yyyy-MM-dd')) rk
from
user_login_detail
group by
user_id,date_format(login_ts,'yyyy-MM-dd')
)t1
)t2
group by
t2.user_id,t2.login_date_rk
-- 求出每个用户的金币总数
select
t3.user_id,
sum(t3.coin_cn) sum_coin_cn
from
(
select
t2.user_id,
max(t2.counti_cn)+sum(if(t2.counti_cn%3=0,2,0))+sum(if(t2.counti_cn%7=0,6,0)) coin_cn
from
(
select
t1.user_id,
t1.login_date,
date_sub(t1.login_date,t1.rk) login_date_rk,
count(*)over(partition by t1.user_id, date_sub(t1.login_date,t1.rk) order by t1.login_date) counti_cn
from
(
select
user_id,
date_format(login_ts,'yyyy-MM-dd') login_date,
rank()over(partition by user_id order by date_format(login_ts,'yyyy-MM-dd')) rk
from
user_login_detail
group by
user_id,date_format(login_ts,'yyyy-MM-dd')
)t1
)t2
group by
t2.user_id,t2.login_date_rk
)t3
group by
t3.user_id
order by
sum_coin_cn desc