mysql 查询一个用户连续签到天数

我有个平台是有签到功能的,我需要判断这个用户连续在这个平台上签到多少天了 给他不同的积分。
例如今天是4月26号,从4月15号开始每天都签到了,那就是连续签到12天,4月13号也签到了,但是4月14号没签到,
mysql语句怎么写呢

阅读 15.1k
5 个回答

一般都会存储一下连续签到的天数的,如果没有存储,我们以前做过的一个方式是我们签到是采用时间戳存储的然后获取签到的时间戳,一般我们都是获取一个月的(如果这个月签到满了,就在获取一次前一个月的),然后在 php 里面循环一下天数计算出来的。后来这种方式比较慢,我们就单独记录签到天数了

数据库设计问题.
因为要统计连续天数,不可能每天都记录一条(想象一下银行记录用户任意天数的余额).
会计上的做法叫年积数的算法.即记录某个时间点至另一时间点余额不变(连续)
表设计,大致如下:

clipboard.png

结束时间-起始时间=天数.积分换算,就像税收那样,加成计算就行了.

你的业务规则里,应该有个连续 x 天的给多少分的上限,比如连续天>=20则给多少积分。

那么我们记住这个 x,在db里 select * from tb where uid = 10086 order by dt desc limit x

然后在程序里判断最多连续了多少天,加上对应的分数即可。

新手上路,请多包涵

借助rownumber即可求解;

如果是连续的记录,那么 diffDate- rn 肯定是相同的!

核心的代码:logindate - row_number() over (partition by userid order by logindate) as groupday

参考:SQL数据分析

SELECT
    count( 1 ) 
FROM
    (
    SELECT
        date_sub( a.ct, INTERVAL 1 DAY ) signDate,
        ( @i := DATE_ADD( @i, INTERVAL - 1 DAY ) ) today 
    FROM
        ( SELECT ct FROM user_reach WHERE user_id = 14864795 ORDER BY ct DESC ) a
        INNER JOIN (
        SELECT
            @i := max( ct ) AS signMax 
        FROM
            user_reach 
        WHERE
            user_id = 14864795 
            AND ( TO_DAYS( ct ) = TO_DAYS( curdate()) OR TO_DAYS( ct ) = TO_DAYS( DATE_ADD( curdate(), INTERVAL - 1 DAY ) ) ) 
        ) b 
    WHERE
        b.signMax IS NOT NULL 
        AND TO_DAYS(
        DATE_ADD( @i, INTERVAL - 1 DAY )) = TO_DAYS( date_sub( a.ct, INTERVAL 1 DAY ) ) 
    ) c

https://www.jianshu.com/p/30f...

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题