mysql/mariadb 中的数据库条目连续记录 - 直到今天

Posted

技术标签:

【中文标题】mysql/mariadb 中的数据库条目连续记录 - 直到今天【英文标题】:Database entry streak in mysql/mariadb - until today 【发布时间】:2020-08-08 07:10:45 【问题描述】:

我昨天问了这个问题,但我似乎并没有说得足够清楚,所以我要添加一些信息以使一切清楚。

考虑以下 2 个表格:

0_12_table

ID userID text timestamp
1  1      bla  2020-08-07 10:30:00
2  1      blub 2020-08-06 11:30:00
3  1      abc  2020-08-05 09:20:00
4  1      def  2020-08-04 06:13:00
5  2      ghi  2020-08-02 08:05:00
6  2      abc  2020-08-05 10:20:00
7  3      def  2020-08-04 07:13:00
8  4      ghi  2020-08-02 09:05:00
9  5      jkl  2020-08-07 06:30:00
10 5      mno  2020-08-08 08:32:00

12_24_table:

ID userID text timestamp
1  1      bla  2020-08-07 19:30:00
2  1      blub 2020-08-06 21:30:00
3  1      abc  2020-08-05 19:20:00
4  2      def  2020-08-04 16:13:00
5  2      ghi  2020-08-02 18:05:00
6  2      abc  2020-08-05 20:20:00
7  3      def  2020-08-04 17:13:00
8  4      ghi  2020-08-02 19:05:00
9  5      jkl  2020-08-07 20:13:00

基本上,用户可以(并且很乐意这样做)在 00:00 到 12:00 之间以及在 12:01 到 23:59 之间在数据库中添加一个条目。

现在我想奖励他们添加连续条目。每当他们错过时间范围时,那个“计数器”就会重置为 0...

在上面给定的数据中,用户 ID 为 1 的用户现在连续 3 天(在我的时间,现在是上午 9 点),但只要在上午 12 点之后,他就没有再做一次条目,计数器将被设置为 0 并且连续结束,因为他错过了早上添加条目。

用户 ID 为 2,3 和 4 的用户根本不会出现连击。如果缺少一个早上或晚上的条目,则连续取消。

用户 ID 为 5 的用户在 12:01 到 23:59 的时间范围内每次进入时,连续 1 次都会增加到 2 次。

我希望你明白其中的逻辑。重要的是,如果他在 2 天前连续 10 次,这并不重要。每当有条目丢失时,连胜将重置为 0。因此,如果某天早上 12 点之前没有条目,或者晚上 23:59 之前没有条目,那么连胜就消失了。它总是使用今天作为参考,因此它确实是“直到今天的连续条目”。

到目前为止,我得到的答案似乎很接近:

select min(dte), max(dte), count(*)
from (select dte, (@rn := @rn + 1) as seqnum
      from (select dte
            from ((select date(timestamp) as dte, 1 as morning, 0 as evening
                   from morning
                  ) union all
                  (select date(timestamp) as dte, 0 as morning, 1 as evening
                   from evening
                  )
                 ) me
            group by dte
            having sum(morning) > 0 and sum(evening) > 0
            order by dte
           ) d cross join
           (select @rn := 0) params
     ) me
group by dte - interval seqnum day
order by count(*) desc
limit 1;

但是,到目前为止我还没有介绍用户ID,最大的问题是:它只需要最后一个连胜,无论到今天是否有差距。但是,如前所述,它总是以今天为参考。

我希望有人可以在这里帮助我。

最后的重要信息:我使用的是 MariaDB 10.1.45,因此“WITH”或“ROWNUM()”不可用,目前无法更新。

提前致谢!

【问题讨论】:

【参考方案1】:

在使用窗口函数的较新版本中,这确实会更简单。但是您可以调整变量以获得用户的所有条条纹:

select userid, count(*) as length
from (select dte, (@rn := @rn + 1) as seqnum
      from (select dte
            from ((select userid, date(timestamp) as dte, 1 as morning, 0 as evening
                   from morning
                  ) union all
                  (select userid, date(timestamp) as dte, 0 as morning, 1 as evening
                   from evening
                  )
                 ) me
            group by userid, dte
            having sum(morning) > 0 and sum(evening) > 0
            order by userid, dte
           ) d cross join
           (select @rn := 0) params
     ) me
group by userid, dte - interval seqnum day
order by count(*) desc;

事实证明,对于这个问题,“全局”序列和局部序列一样有效,因此变量的使用仍然很简单。更改的是 group byorder by 子句。

然后您可以将其用作子查询来获取最大值:

select userid, max(seq)
from (select userid, count(*) as seq
      from (select dte, (@rn := @rn + 1) as seqnum
            from (select dte
                  from ((select userid, date(timestamp) as dte, 1 as morning, 0 as evening
                         from morning
                        ) union all
                        (select userid, date(timestamp) as dte, 0 as morning, 1 as evening
                         from evening
                        )
                       ) me
                  group by userid, dte
                  having sum(morning) > 0 and sum(evening) > 0
                  order by userid, dte
                 ) d cross join
                 (select @rn := 0) params
           ) me
      group by userid, dte - interval seqnum day
     ) u
group by userid;

注意:没有条纹的用户将被过滤掉。您可以在外部查询中使用left join 将它们放回原处。但是,您确实需要一个包含所有 用户 的表,而不是您的两个单独的表,所以我没有打扰。

【讨论】:

嘿,谢谢你的回答.. 不幸的是,结果仍然不正确......我用我的表试了一下,结果是 2,它应该是 0,因为用户没有最后一天添加一个条目...还在select语句中添加了几次userid 看到这个小提琴:dbfiddle.uk/… 并将其与我上面的描述进行比较......即使没有条目,用户仍然有连续性...... 另外,当做一些改变时,它会做一些奇怪的事情,在这种情况下,userID 2 在结果中有 2 次出现:dbfiddle.uk/…

以上是关于mysql/mariadb 中的数据库条目连续记录 - 直到今天的主要内容,如果未能解决你的问题,请参考以下文章

数据库MySQL/mariadb知识点——日志记录二进制日志

mysql/mariadb学习记录——连接查询(JOIN)

mysql/mariadb学习记录——limit

MySQL/Mariadb 每条记录的开销?

连续更新条目中的值

mysql/mariadb学习记录——查询2