【问题标题】:Select longest streak in days from mysql database?从mysql数据库中选择最长的连续几天?
【发布时间】:2018-11-18 16:07:11
【问题描述】:

首先,我在 Google 和 Stackoverflow 上都发现了很多类似的问题,但我似乎无法掌握如何正确地做到这一点。

我有一个如下所示的表格:

    id      ms_date
    ------------------
    1     2018-11-18
    2     2018-11-18
    3     2018-11-20
    4     2018-11-22
    5     2018-11-25
    6     2018-11-26
    7     2018-11-26
    8     2018-11-27
    9     2018-11-28
   10     2018-11-29

我需要做的是从该表中获得Days 中最长的连胜记录。

所以在上面的例子中,最长的连续是4 days

我发现了这个:https://dzone.com/articles/how-to-find-the-longest-consecutive-series-of-even

它解释了他想要做什么,这与我想要实现的目标相似,但是它的解释/写得非常糟糕,以至于我无法理解它。

我还需要找出这些日期之间的 GAP 并重新开始计算连续次数。同样在上面的示例中,由于日期之间存在间隔,Current Streak 应该是 3 Days

我尝试使用上面链接中的代码,但它是基于 SQL 的,而且代码中有一些奇怪的 WITH 字词,根本没有意义。

有没有使用 PHP 和 Mysql 的简单方法来实现这一点?

有人可以就这个问题提出建议吗?

提前致谢。

编辑:

我似乎无法在我的 PHPMYADMIN 中找到软件版本,但这是我可以在数据库服务器部分看到的:

Server: Localhost via UNIX socket
Server type: MariaDB
Server connection: SSL is not being used Documentation
Server version: 10.0.37-MariaDB-0+deb8u1 - (Debian)
Protocol version: 10
User: freemind@localhost
Server charset: UTF-8 Unicode (utf8)

第二次编辑:

根据以下答案尝试了以下方法,但我一无所获:

$sql_COUNT = "SELECT COUNT(*) max_streak 
  FROM 
     ( SELECT x.*
            , CASE WHEN @prev = val - 1 THEN @i:=@i ELSE @i:=@i+1 END i
            , @prev:=val  
         FROM 
            ( SELECT DISTINCT ms_date FROM MY_TABLE ) x
         JOIN 
            ( SELECT @prev:=null,@i:=0 ) vars 
        ORDER 
           BY ms_date
     ) a 
 GROUP 
    BY i 
 ORDER 
    BY max_streak DESC LIMIT 1";
$query_COUNT = mysqli_query($db_conx, $sql_COUNT);
$productCount_COUNT = mysqli_num_rows($query_COUNT); // count the output amount

echo $productCount_COUNT;

第三次编辑:

以下代码在我的页面上回显1,但基于我在MYSQL 数据库中的内容,它应该回显4

$sql_COUNT = "SELECT COUNT(*) AS max_streak 
  FROM 
     ( SELECT x.*
            , CASE WHEN @prev = ms_date - 1 THEN @i:=@i ELSE @i:=@i+1 END i
            , @prev:=ms_date  
         FROM 
            ( SELECT DISTINCT ms_date FROM MY_TABLE ) x
         JOIN 
            ( SELECT @prev:=null,@i:=0 ) vars 
        ORDER 
           BY ms_date
     ) a 
 GROUP 
    BY i 
 ORDER 
    BY max_streak DESC LIMIT 1";
$query_COUNT = mysqli_query($db_conx, $sql_COUNT);

$productCount_COUNT = mysqli_num_rows($query_COUNT); // count the output amount

echo $productCount_COUNT;   

第四次编辑:

我不确定以下答案是否经过测试,但对我不起作用。

我尝试了以下操作,即使我没有收到任何错误,我也只看到一个空白页,这意味着代码不起作用:

$sql_COUNT = "SELECT COUNT(*) max_streak 
  FROM 
     ( SELECT x.*
            , CASE WHEN @prev = ms_date - INTERVAL 1 DAY THEN @i:=@i ELSE @i:=@i+1 END i
            , @prev:=ms_date  
         FROM 
            ( SELECT DISTINCT ms_date FROM MY_TABLE ORDER BY ms_date ) x
         JOIN 
            ( SELECT @prev:=null,@i:=0 ) vars 
     ) a 
 GROUP 
    BY i 
 ORDER 
    BY max_streak DESC";
$query_COUNT = mysqli_query($db_conx, $sql_COUNT);

$count = mysqli_fetch_array($query_COUNT);
echo $count[0];

【问题讨论】:

标签: php mysql date


【解决方案1】:

考虑以下...

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(id SERIAL PRIMARY KEY
,val INT NOT NULL
);

INSERT INTO my_table VALUES
(1   , 11),
(2   , 11),
(3   , 12),
(4   , 13),
(5   , 14),
(6   , 17),
(7   , 18),
(8   , 20),
(9   , 21),
(10  , 22);

SELECT COUNT(*) max_streak 
  FROM 
     ( SELECT x.*
            , CASE WHEN @prev = val - 1 THEN @i:=@i ELSE @i:=@i+1 END i
            , @prev:=val  
         FROM 
            ( SELECT DISTINCT val FROM my_table ) x
         JOIN 
            ( SELECT @prev:=null,@i:=0 ) vars 
        ORDER 
           BY val
     ) a 
 GROUP 
    BY i 
 ORDER 
    BY max_streak DESC LIMIT 1;
+------------+
| max_streak |
+------------+
|          4 |
+------------+
1 row in set (0.01 sec)

编辑:

如果你使用日期,那么逻辑是相同的,但你只需要替换一些日期算术......

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(id SERIAL PRIMARY KEY
,val DATE NOT NULL
);

INSERT INTO my_table VALUES
(1   , '2018-11-11'),
(2   , '2018-11-11'),
(3   , '2018-11-12'),
(4   , '2018-11-13'),
(5   , '2018-11-14'),
(6   , '2018-11-17'),
(7   , '2018-11-18'),
(8   , '2018-11-20'),
(9   , '2018-11-21'),
(10  , '2018-11-22');

SELECT COUNT(*) max_streak 
  FROM 
     ( SELECT x.*
            , CASE WHEN @prev = val - INTERVAL 1 DAY THEN @i:=@i ELSE @i:=@i+1 END i
            , @prev:=val  
         FROM 
            ( SELECT DISTINCT val FROM my_table ) x
         JOIN 
            ( SELECT @prev:=null,@i:=0 ) vars 
        ORDER 
           BY val
     ) a 
 GROUP 
    BY i 
 ORDER 
    BY max_streak DESC LIMIT 1;
+------------+
| max_streak |
+------------+
|          4 |
+------------+

纯粹主义者会(正确地)争辩说我以不正确的方式使用@variable 赋值 - 但这只是我养成的一个坏习惯。也就是说,我认为正确的赋值方法如下,但如果我弄错了,毫无疑问有人会告诉我......

SELECT COUNT(*) max_streak 
  FROM 
     ( SELECT x.*
            , CASE WHEN @prev = val - INTERVAL 1 DAY THEN @i:=@i ELSE @i:=@i+1 END i
            , @prev:=val  
         FROM 
            ( SELECT DISTINCT val FROM my_table ORDER BY val ) x
         JOIN 
            ( SELECT @prev:=null,@i:=0 ) vars 
     ) a 
 GROUP 
    BY i 
 ORDER 
    BY max_streak DESC LIMIT 1;

如果你想把它捆绑在一些 PHP 中,我猜它可能看起来像这样(尽管从接下来的内容应该很明显,应用程序代码并不是我的强项)...

<?php

require('path/to/connection/stateme.nts');

$query = "
SELECT COUNT(*) max_streak
  FROM
     ( SELECT x.*
            , CASE WHEN @prev = val - INTERVAL 1 DAY THEN @i:=@i ELSE @i:=@i+1 END i
            , @prev:=val
         FROM
            ( SELECT DISTINCT val FROM MY_TABLE ORDER BY val ) x
         JOIN
            ( SELECT @prev:=null,@i:=0 ) vars
     ) a
 GROUP
    BY i
 ORDER
    BY max_streak DESC
 LIMIT 1;
";

$result = mysqli_query($conn, $query) or die(mysqli_error($conn));

$row = mysqli_fetch_assoc($result);

print_r($row);

?>

-- outputs

Array ( [max_streak] => 4 ) 

【讨论】:

  • 抱歉,我很容易混淆,但您的示例中的日期在哪里?
  • 您必须更改使用“val”计算的位置才能使用日期计算。
  • 完成了,但没有工作。我收到此错误:您的 SQL 语法有错误;检查与您的 MariaDB 服务器版本相对应的手册,以在第 1 行的 'max_streak FROM ( SELECT x.* , CASE WHEN @prev = val - 1 TH' 附近使用正确的语法
  • @Carmen 好吧,14 个月前这不是一个愚蠢的问题
  • @strawberry 有没有办法让连胜也开始?
猜你喜欢
  • 2010-09-23
  • 2019-06-11
  • 1970-01-01
  • 2015-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-18
  • 2013-02-04
相关资源
最近更新 更多