题解 | #最大连续回答天数大于等于3天的用户及其对应等级#

某乎问答最大连续回答问题天数大于等于3天的用户及其对应等级

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

题目:

统计最大连续回答问题的天数大于等于3天的用户及其等级。若有多条符合条件的数据,按author_id升序排序


难点:

  • 本题目最大的难点就在于:如何判断几个日期是否连续的 —— 当一组日期按照升序排序时,如果某几个日期是连续的,它们减去本身的DENSE RANK,会发现都是相减的结果都是同一天

(不得不说,不知道是哪位先发现这个切入角度的的,真的是个人才。要是哪位知道这种数学规律的出处,求分享!)

  • 另外,我发现大多数回答忽略了一个特殊情况(虽然题目实例中并没有考虑到):若一个用户有10次连续登录超过三天的情况,则该用户会得出10组“同一天”日期及其对应的连续天数(10个大于等于3的随机整数) —— 针对这一特殊情况,可在最终的答案中再嵌套一层MAX查询

解题步骤

步骤 1:找出每个用户的答题日期及日期的升序排名

  • 注意,因为用户可在同一天答题多次,因此需要使用DISTINCT进行去重
    SELECT DISTINCT a1.author_id, a2.author_level, answer_date,
                    DENSE_RANK() OVER (PARTITION BY a1.author_id ORDER BY answer_date ASC) AS ranking
    FROM answer_tb AS a1 LEFT OUTER JOIN author_tb AS a2
    ON a1.author_id = a2.author_id

步骤 2:根据“答题日期 - 排序”所得出的日期进行聚合,计算相减日期为同一天的对应行数,即为连续答题天数

  • 最主要的是要知道:DATE_SUB()得出的结果日期,也是聚合字段之一,要根据该结果计算对应的行数
  • 随后,再把连续答题天数大于等于3的筛选出来即可
    SELECT author_id, 
         author_level, 
         COUNT(author_id) AS days_cnt
    FROM
         (SELECT DISTINCT a1.author_id, a2.author_level, answer_date,
                 DENSE_RANK() OVER (PARTITION BY a1.author_id ORDER BY answer_date ASC) AS ranking
          FROM answer_tb AS a1 LEFT OUTER JOIN author_tb AS a2
          ON a1.author_id = a2.author_id) AS t1
    GROUP BY author_id, author_level, DATE_SUB(answer_date, INTERVAL ranking DAY)
    HAVING days_cnt >= 3
    ORDER BY author_id ASC;

步骤 3:若是同一用户有多次连续答题超过3次的情况,则仍需嵌套一层MAX函数查询,找出每个用户的最大连续天数即可

  • 其实步骤2的解法已经能通过本次题目了,但考虑到仍有一个特殊情况,再完善一下查询语句
    SELECT author_id, author_level, MAX(days_cnt) AS days_cnt
    FROM
        (SELECT author_id,
                author_level,
                COUNT(author_id) AS days_cnt
         FROM
              (SELECT DISTINCT a1.author_id, a2.author_level, answer_date,
                      DENSE_RANK() OVER (PARTITION BY a1.author_id ORDER BY answer_date ASC) AS ranking
               FROM answer_tb AS a1 LEFT OUTER JOIN author_tb AS a2
               ON a1.author_id = a2.author_id) AS t1
         GROUP BY author_id, author_level, DATE_SUB(answer_date, INTERVAL ranking DAY)
         HAVING days_cnt >= 3) AS t2
    GROUP BY author_id, author_level
    ORDER BY author_id ASC;
全部评论

相关推荐

一天代码十万三:这都不能算简历吧
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客企业服务