开发者社区> 问答> 正文

检查连续x天-数据库中给定的时间戳?mysql

有人能给我一个想法或暗示,您如何在存储登录名(用户ID,时间戳)的数据库表(MySQL)中连续检查X天?

Stackoverflow会做到这一点(例如,像发烧友这样的徽章-如果您连续30天左右登录...)。您将要使用什么功能,或者怎么做呢?

像SELECT 1 FROM login_dates WHERE ...什么?

展开
收起
保持可爱mmm 2020-05-17 19:28:05 502 0
1 条回答
写回答
取消 提交回答
  • 您可以通过将移位的自我外部联接与变量结合使用来完成此操作。查看此解决方案:

    SELECT IF(COUNT(1) > 0, 1, 0) AS has_consec FROM ( SELECT * FROM ( SELECT IF(b.login_date IS NULL, @val:=@val+1, @val) AS consec_set FROM tbl a CROSS JOIN (SELECT @val:=0) var_init LEFT JOIN tbl b ON a.user_id = b.user_id AND a.login_date = b.login_date + INTERVAL 1 DAY WHERE a.user_id = 1 ) a GROUP BY a.consec_set HAVING COUNT(1) >= 30 ) a 这将返回一个1或一个0基于用户是否已经在连续30天或以上的记录ANYTIME过去。

    这个查询的首当其冲是在第一个子选择中。让我们仔细看看,以便我们更好地了解其工作原理:

    使用以下示例数据集:

    CREATE TABLE tbl ( user_id INT, login_date DATE );

    INSERT INTO tbl VALUES (1, '2012-04-01'), (2, '2012-04-02'), (1, '2012-04-25'), (2, '2012-04-03'), (1, '2012-05-03'), (2, '2012-04-04'), (1, '2012-05-04'), (2, '2012-05-04'), (1, '2012-05-05'), (2, '2012-05-06'), (1, '2012-05-06'), (2, '2012-05-08'), (1, '2012-05-07'), (2, '2012-05-09'), (1, '2012-05-09'), (2, '2012-05-11'), (1, '2012-05-10'), (2, '2012-05-17'), (1, '2012-05-11'), (2, '2012-05-18'), (1, '2012-05-12'), (2, '2012-05-19'), (1, '2012-05-16'), (2, '2012-05-20'), (1, '2012-05-19'), (2, '2012-05-21'), (1, '2012-05-20'), (2, '2012-05-22'), (1, '2012-05-21'), (2, '2012-05-25'), (1, '2012-05-22'), (2, '2012-05-26'), (1, '2012-05-25'), (2, '2012-05-27'), (2, '2012-05-28'), (2, '2012-05-29'), (2, '2012-05-30'), (2, '2012-05-31'), (2, '2012-06-01'), (2, '2012-06-02'); 该查询:

    SELECT a., b., IF(b.login_date IS NULL, @val:=@val+1, @val) AS consec_set FROM tbl a CROSS JOIN (SELECT @val:=0) var_init LEFT JOIN tbl b ON a.user_id = b.user_id AND a.login_date = b.login_date + INTERVAL 1 DAY WHERE a.user_id = 1 将产生:

    结果示例

    如您所见,我们正在做的是将联接表移动 +1天。对于与前一天不连续的每一天,NULLLEFT JOIN都会生成一个值。

    现在,我们知道其中非连续的日子中,我们可以使用一个变量来区分各组通过检测转移表的行是否是连续数日NULL。如果是NULL,则日期不是连续的,因此只需增加变量即可。如果它们是NOT NULL,则不要增加变量:

    突出显示分组的结果

    在使用递增变量对每组连续天进行了区分之后,只需对每个“组”(在consec_set列中定义)进行分组,然后使用HAVING过滤掉少于指定连续天数的任何组,就很简单了。(在您的示例中为30):

    按consec_set列分组的结果

    最后,我们包装THAT查询并简单地计算连续30天或更多天的集合数。如果有一个或多个这些集合,则返回1,否则返回0。来源:stack overflow

    2020-05-17 19:32:30
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
搭建电商项目架构连接MySQL 立即下载
搭建4层电商项目架构,实战连接MySQL 立即下载
PolarDB MySQL引擎重磅功能及产品能力盛大发布 立即下载

相关镜像