【问题标题】:Retrieve running-total record growth over time in mysql在mysql中检索随时间推移的运行总记录增长
【发布时间】:2013-04-03 18:54:12
【问题描述】:

我有一个 Drupal 站点,其中有一个跟踪用户的表。我想做的是随着时间的推移绘制会员增长图。所以我想按摩mysql返回这样的东西:

date | # of users (total who have registered up to the given date)
1/1/2014 | 0
1/2/2014 | 2
1/3/2014 | 10

其中“# of users”是截至给定日期注册帐户的用户总数(running-total)--不是在该特定日期注册的用户数(这很容易检索)。

{users} 表的每一行都有一个uid 列、一个name 列和一个created(时间戳)列。

所以我的{users} 表中的示例记录将是:

name: John Smith
uid: 526
created: 1365844220

【问题讨论】:

  • 你能提供样本记录吗?
  • 查询类似于 SUM(#ofusersColumn) 带有某种日期之前的子句
  • @JW 我已经用示例记录更新了我的原始帖子。基本上,唯一相关的是created 列。
  • @user466764 我想检索多个日期的运行总数(我可以绘制图表),而不仅仅是在某个特定日期注册的用户总数。我希望 mysql 返回类似:1/1/2014 : 0 | 1/2/2014 : 2 | 1/3/2014 : 10
  • 您是否希望每天返回一行,无论当天是否有用户注册,还是仅在用户注册的日子返回?如果你想要每一天的行,你是否已经设置了一个日期表来保存每一天的日期?

标签: mysql count cumulative-sum


【解决方案1】:

试试:

select u.created, count(*)
from (select distinct date(created) created from `users`) u
join `users` u2 on u.created >= date(u2.created)
group by u.created

SQLFiddle here.

【讨论】:

  • 谢谢@Mark!这看起来很有希望......不幸的是created是一个unix时间戳而不是一个日期时间(对不起,如果我不清楚),但我猜我可以使用DATE(创建)稍微摆弄它来工作...
  • @JordanMagnuson:我更新了我的查询,用date(created)截断日期。
  • 非常感谢马克。您的解决方案确实适用于我所述的用例。不幸的是,我在应用程序中遇到了一些问题,无论是在效率领域(处理数万条记录时查询似乎非常慢),还是在为我的项目实现特定范围和日期格式需求时(我做到了)不要在原始问题中发布)。我用最终使用的代码发布了自己的答案,但非常感谢您的解决方案。
  • @JordanMagnuson:当我提出我的答案时,我没有意识到性能会成为一个问题 - 我曾考虑过使用变量的答案,但这更容易编码。
  • @Mark: 好像有个bug,虽然我想不通,请看这个sqlfiddle.com/#!8/b56bd/1和计数
【解决方案2】:

我最终使用了一个包含变量的解决方案,基于 here 发布的 Stack Overflow 答案。与提供的其他答案相比,此解决方案似乎更灵活、更高效。

  SELECT u.date,
  @running_total := @running_total + u.count AS count
  FROM (
    SELECT COUNT(*) AS count, DATE_FORMAT(FROM_UNIXTIME(created), '%b %d %Y') AS date
    FROM {users}
    WHERE created >= :start_time AND created <= :end_time
    GROUP BY YEAR(FROM_UNIXTIME(created)), MONTH(FROM_UNIXTIME(created)), DAY(FROM_UNIXTIME(created))
  ) u
  JOIN (
    SELECT @running_total := u2.starting_total
    FROM (
      SELECT COUNT(*) as starting_total
      FROM {users}
      WHERE created < :start_time
    ) u2
  ) initialize;

请注意,分组依据、日期格式和范围要求只是我的特定项目的具体细节。 此解决方案的更通用形式(根据原始问题)是:

  SELECT u.date,
  @running_total := @running_total + u.count AS count
  FROM (
    SELECT COUNT(*) AS count, DATE(FROM_UNIXTIME(created)) AS date
    FROM {users}
    GROUP BY date
  ) u
  JOIN (
    SELECT @running_total := 0
  ) initialize;

【讨论】:

  • 这对我来说是一个重要的救星。对于后代:请注意,这种方法也比接受的答案快得多。注意:如果我不提供开始时间(您可以省略结束时间),我的计数将被取消。
【解决方案3】:

不知道表结构,所以根据需要调整查询

SELECT DATE(created), COUNT(*) AS Users FROM users GROUP BY DATE(created)

当您只想显示添加注册用户的日期时

HAVING COUNT(*) > 0

在查询的 and 处

【讨论】:

  • 这会给我每个日期注册的用户数量,但不是到给定日期注册的用户总数......(请参阅我原始帖子中的粗体句)
猜你喜欢
  • 2021-06-21
  • 2020-09-21
  • 1970-01-01
  • 1970-01-01
  • 2020-07-03
  • 2012-04-15
  • 2016-02-13
  • 2014-03-14
  • 2019-04-25
相关资源
最近更新 更多