有人能给我一个想法或暗示,您如何在存储登录名(用户ID,时间戳)的数据库表(MySQL)中连续检查X天?
Stackoverflow会做到这一点(例如,像发烧友这样的徽章-如果您连续30天左右登录...)。您将要使用什么功能,或者怎么做呢?
像SELECT 1 FROM login_dates WHERE ...什么?
您可以通过将移位的自我外部联接与变量结合使用来完成此操作。查看此解决方案:
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
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。