这道题我觉得没有说清楚,
days_cnt到底是啥?
  • 是连续回答天数中最大的那天?
  • 还是回答天数的总和?
这不重要,只是连续签到问题的延伸,无非加几张表而已

思路重点,在于计算连续签到的天数
【核心思想】在于如果连续签到,则签到日期与签到日期的排序差值所得的日期是一样的
【解题思路】
  • 步骤1:排序
  • 步骤2:作差
  • 步骤3:分组计数
以本题为例:
  • 第一步:排序。按照回答日期,因为一天可能回答多个问题,所以用dense_rank()
select author_id,
answer_date,
dense_rank() over (PARTITION BY author_id order by answer_date) ranking
from answer_tb
第二步:作差。用answer_date-ranking,得到日期dt。(dt是判断连续天数的关键)
select t.author_id,
t.answer_date,
t.answer_date-t.ranking dt
FROM
(
    #第一步
)t
  • 第三步:分组。按照author_id和dt分组,依照answer_date去重计数
 本题涉及连续回答天数>=3,所以分组后,还需使用having筛选数据
select t1.author_id,
count(DISTINCT t1.answer_date) cnt from
(
#第二步:作差。用answer_date-ranking,得到日期dt。(dt是判断连续天数的关键)
select t.author_id,
t.answer_date,
t.answer_date-t.ranking dt
FROM
(#第一步:排序。按照回答日期,因为一天可能回答多个问题,所以用dense_rank()
select author_id,
answer_date,
dense_rank() over (PARTITION BY author_id order by answer_date) ranking
from answer_tb
)t
)t1
GROUP BY t1.author_id,t1.dt
having count(DISTINCT t1.answer_date)>=3
至此,本题完成大半


回到开篇,
  • 如果days_cnt是连续签到天数的最大值,那在对author_id分组,使用max()得到最大天数
  • 如果days_cnt是符合条件的author_id的签到天数总和,则对原始表按照author_id分组计算天数即可
至于,符合条件的用户对应等级,通过连接表即可实现,不说啥了

最后,本题完整代码,我按最简单的情况计算,符合条件的用户只有一次连续签到天数>=3,days_cnt是连续签到的最大值
select a.author_id,b.author_level,a.days_cnt FROM
(select t1.author_id,
count(distinct t1.answer_date) days_cnt
from 
(
select t.author_id,
t.answer_date,
t.answer_date-t.ranking dt
FROM
(
select author_id,
answer_date,
dense_rank() over (PARTITION BY author_id order by answer_date) ranking
from answer_tb
)t
)t1
GROUP BY t1.author_id,t1.dt
having count(distinct t1.answer_date)>=3)a
LEFT JOIN author_tb b
on a.author_id=b.author_id
order by a.author_id
;