Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql SQL在表中查找连续月份的用户数_Mysql_Sql - Fatal编程技术网

Mysql SQL在表中查找连续月份的用户数

Mysql SQL在表中查找连续月份的用户数,mysql,sql,Mysql,Sql,我有一个包含以下列的表 email ---- created at abc@gmail.com 2019-12-12 16:03:34 rp@gamil.com 2019-11-12 16:03:34 abc@gmail.com 2020-1-12 16:03:34 er@gmail.com 2020-1-12 16:03:34 我想设计一个查询,返回连续两个月内注册的过期电子邮件数。我不是一个查询新手,一

我有一个包含以下列的表

email        ----        created at
abc@gmail.com        2019-12-12 16:03:34
rp@gamil.com         2019-11-12 16:03:34
abc@gmail.com        2020-1-12 16:03:34
er@gmail.com         2020-1-12 16:03:34
我想设计一个查询,返回连续两个月内注册的过期电子邮件数。我不是一个查询新手,一直在努力为这个问题提出一个查询


对于上述问题,请输入查询
abc@gmail.com
连续几个月注册了两次

您可以使用
存在
查询来检查是否存在上个月也注册过的电子邮件:

SELECT DISTINCT email
FROM yourtable t1
WHERE EXISTS (SELECT *
              FROM yourtable t2
              WHERE t2.email = t1.email 
                AND DATE_FORMAT(t2.createdat, '%Y%m') = DATE_FORMAT(t1.createdat - INTERVAL 1 MONTH, '%Y%m'))
示例数据的输出

abc@gmail.com


我们使用
DISTINCT
,因此如果一个电子邮件地址连续注册超过一个月,我们不会收到同一封电子邮件的多份副本。

通过对
month+1
email
进行自加入(同时考虑到12月到1月的过渡),这应该可以起作用:

SELECT
    *
FROM
    (
        SELECT
            email,
            YEAR( created ) AS createdYear,
            MONTH( created ) AS createdMonth
        FROM
            table
    ) AS t

    INNER JOIN
    (
        SELECT
            email,
            YEAR( created ) AS createdYear,
            MONTH( created ) AS createdMonth
        FROM
            table
    ) AS monthPlus1 ON 
        t.email = monthPlus1.email
        AND
        (
            (
                t.createdMonth = monthPlus1.createdMonth + 1
                AND
                t.createdYear = monthPlus1.createdYear
            )
            OR
            (
                t.createdMonth = 12
                AND
                monthPlus1.createdMonth = 1
                AND
                t.createdYear + 1 = monthPlus1.createdYear
            )
        )
此查询中的日期逻辑有点粗糙-可以通过将月份表示为单个
日期
值或自epoc以来的整数月,而不是
年+月
元组来改进它。

您可以使用
滞后()。如果发生这种情况,则
lag()

select t.email
from (select t.*
             lag(created_at) over (partition by t.email order by created_at) as prev_created_at
      from t
     ) t
where extract(year_month from created_at) = extract(year_month from (prev_created_at + interval 1 month));

如果这种情况可能发生多次,您可能需要
选择distinct

那么基本上您想要每个月的电子邮件数量?这些答案中有一个解决了您的问题吗?如果没有,您能提供更多信息来帮助回答吗?这只会返回连续一个月的结果,而不是连续两个月的结果。@Dai这是OP想要的,请查看问题中的样本数据和预期输出啊,对不起!我错了!此查询是否处理第1个月为2019年12月,第2个月为2020年1月的情况?我不认为您的比较中包含了
,但不正确,因为2020年1月和2018年12月被认为是连续的。谢谢你指出,我已经改正了