Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.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计算每用户最近60天的streak_Mysql - Fatal编程技术网

Mysql计算每用户最近60天的streak

Mysql计算每用户最近60天的streak,mysql,Mysql,我想从这个mysql表计算60天内每个用户的最长连胜。Streak表示用户在这一天有一个条目 +-----+------------+---------------------+ | id | user | date | +-----+------------+---------------------+ | 3 | test1 | 2014-06-10 23:55:01 | | 4 | test2 | 2014-06-10

我想从这个mysql表计算60天内每个用户的最长连胜。Streak表示用户在这一天有一个条目

+-----+------------+---------------------+
| id  | user       | date                |
+-----+------------+---------------------+
|   3 | test1      | 2014-06-10 23:55:01 |
|   4 | test2      | 2014-06-10 02:01:06 |
|   5 | test1      | 2014-06-11 23:55:06 |
|   6 | test2      | 2014-06-11 23:55:07 |
|   7 | test1      | 2014-06-12 23:55:07 |
|   9 | test1      | 2014-06-13 23:55:07 |
|   10| test2      | 2014-06-13 23:55:07 |
输出应如下所示:

test1  4
test2  2 no entry on  2014-06-12

但我不知道如何正确执行此操作。

一种方法是使用MySQL用户变量。对于大型集合,这不一定是最有效的方法,因为它具体化了两个内联视图

SELECT s.user
     , MAX(s.streak) AS longest_streak
  FROM ( SELECT IF(@prev_user = o.user AND o.date = @prev_date + INTERVAL 1 DAY
                  , @streak := @streak + 1
                  , @streak := 1
                ) AS streak
              , @prev_user := o.user AS user
              , @prev_date := o.date AS `date`
           FROM ( SELECT t.user
                       , DATE(t.date) AS `date`
                    FROM mytable t
                   CROSS
                    JOIN (SELECT @prev_user := NULL, @prev_date := NULL, @streak := 1) i
                   WHERE t.date >= DATE(NOW()) + INTERVAL -60 DAY
                   GROUP BY t.user, DATE(t.date)
                   ORDER BY t.user, DATE(t.date)
                ) o
       ) s
 GROUP BY s.user
内联视图有别名,因为我只是初始化了一些用户变量;我们并不真正关心它返回什么,只是因为JOIN操作,我们需要它只返回1行;我们只关心在语句执行的早期初始化用户变量的副作用

别名为o的内联视图获取用户和日期的列表;该规范针对每个日期的一个条目,因此我们可以截断时间部分,只获取日期,并使用GROUPBY子句将其设置为一个不同的集合

别名为s的内联视图处理每一行,并将当前行的值保存到@prev_uu用户变量中。在覆盖值之前,它会将当前行上的值与前一行中保存的值进行比较。如果用户匹配,并且当前行上的日期恰好比上一个日期晚1天,则我们将继续一个streak,因此我们将@streak变量的当前值增加1。否则,前面的条纹被破坏,我们开始一个新的条纹,将@streak重置为1

最后,我们处理s中的行以提取每个用户的最大条纹


此语句仅经过桌面检查,可能有一两个输入错误。

一种方法是使用MySQL用户变量。对于大型集合,这不一定是最有效的方法,因为它具体化了两个内联视图

SELECT s.user
     , MAX(s.streak) AS longest_streak
  FROM ( SELECT IF(@prev_user = o.user AND o.date = @prev_date + INTERVAL 1 DAY
                  , @streak := @streak + 1
                  , @streak := 1
                ) AS streak
              , @prev_user := o.user AS user
              , @prev_date := o.date AS `date`
           FROM ( SELECT t.user
                       , DATE(t.date) AS `date`
                    FROM mytable t
                   CROSS
                    JOIN (SELECT @prev_user := NULL, @prev_date := NULL, @streak := 1) i
                   WHERE t.date >= DATE(NOW()) + INTERVAL -60 DAY
                   GROUP BY t.user, DATE(t.date)
                   ORDER BY t.user, DATE(t.date)
                ) o
       ) s
 GROUP BY s.user
内联视图有别名,因为我只是初始化了一些用户变量;我们并不真正关心它返回什么,只是因为JOIN操作,我们需要它只返回1行;我们只关心在语句执行的早期初始化用户变量的副作用

别名为o的内联视图获取用户和日期的列表;该规范针对每个日期的一个条目,因此我们可以截断时间部分,只获取日期,并使用GROUPBY子句将其设置为一个不同的集合

别名为s的内联视图处理每一行,并将当前行的值保存到@prev_uu用户变量中。在覆盖值之前,它会将当前行上的值与前一行中保存的值进行比较。如果用户匹配,并且当前行上的日期恰好比上一个日期晚1天,则我们将继续一个streak,因此我们将@streak变量的当前值增加1。否则,前面的条纹被破坏,我们开始一个新的条纹,将@streak重置为1

最后,我们处理s中的行以提取每个用户的最大条纹


此对账单仅作桌面检查,可能有一两个输入错误。

你是指连续天数正确的连续天数相关检查戈登的回答Linoff@PatrickPirker你的意思是连续的天数对了连续的天数相关检查一下戈登的答案Linoff@PatrickPirker我刚刚修改了查询,我错过了过去60天的谓词减去60天;我还删除了内联视图中不必要的日期函数,因为我们之前已经处理过了。我还为内联视图返回的列添加了别名。我也在做同样的事情,但我的@M Khalid Junaid有点慢:是的,基本上是相同的方法。只需几个注释:如果第二个和第三个参数之间的间隔小于24小时,TIMESTAMPDIFFDAY函数将返回0;如果参数之间的间隔大于24小时但小于48小时,则可以返回值1。我假设OP只考虑比较中的日期部分,并处理用户在同一日期有多个条目时的条件。一系列条目间隔23小时或25小时的测试用例足以证明它们之间的差异。这里的SQL Fiddle演示:这让我走上了正确的轨道。我明天会重读和研究它+1.非常感谢。我只是修改了查询,我错过了在谓词上减去60天,该谓词应该得到过去的60天;我还删除了内联视图中不必要的日期函数,因为我们之前已经处理过了。我还为内联视图返回的列添加了别名。我也在做同样的事情,但我的@M Khalid Junaid有点慢:是的,基本上是相同的方法。只需几个注释:如果第二个和第三个参数之间的间隔小于24小时,TIMESTAMPDIFFDAY函数将返回0;如果参数之间的间隔大于24小时但小于48小时,则可以返回值1。我假设OP想考虑
比较中的日期部分,并处理用户对同一日期有多个条目时的情况。一系列条目间隔23小时或25小时的测试用例足以证明它们之间的差异。这里的SQL Fiddle演示:这让我走上了正确的轨道。我明天会重读和研究它+1.非常感谢。