MySQL统计最近7天的数据

发布于 2024-09-28 01:04:04 字数 1106 浏览 2 评论 0原文

我有以下架构。

表投票

+------------------+--------------+------+-----+---------------------+----------------+
| Field            | Type         | Null | Key | Default             | Extra          |
+------------------+--------------+------+-----+---------------------+----------------+
| id               | int(10)      | NO   | PRI | NULL                | auto_increment |
| aid              | varchar(10)  | NO   |     |                     |                |
| ip               | varchar(100) | NO   |     |                     |                |
| host             | varchar(200) | NO   |     |                     |                |
| timestamp        | varchar(20)  | NO   |     | 0000-00-00 00:00:00 |                |
| user             | tinytext     | NO   |     | NULL                |                |
| userid           | int(10)      | NO   |     | 0                   |                |
+------------------+--------------+------+-----+---------------------+----------------+

在这里,我想获取过去 7 天内每一天的每次援助的计数,其中“0”表示没有援助投票的日期。这里的时间戳是unix时间戳。

非常感谢任何帮助。

I have the following schema.

Table votes

+------------------+--------------+------+-----+---------------------+----------------+
| Field            | Type         | Null | Key | Default             | Extra          |
+------------------+--------------+------+-----+---------------------+----------------+
| id               | int(10)      | NO   | PRI | NULL                | auto_increment |
| aid              | varchar(10)  | NO   |     |                     |                |
| ip               | varchar(100) | NO   |     |                     |                |
| host             | varchar(200) | NO   |     |                     |                |
| timestamp        | varchar(20)  | NO   |     | 0000-00-00 00:00:00 |                |
| user             | tinytext     | NO   |     | NULL                |                |
| userid           | int(10)      | NO   |     | 0                   |                |
+------------------+--------------+------+-----+---------------------+----------------+

Here I want to get the count of each aid on a day for the last 7 days with "0"s for the dates where there a no votes for aid. timestamp is unix timestamp here.

Any help is highly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧人哭 2024-10-05 01:04:04

MySQL 没有递归功能,因此您只能使用 NUMBERS 表技巧 -

  1. 创建一个仅保存递增数字的表 - 使用 auto_increment 很容易做到:

    如果存在`example`则删除表。`numbers`;
    创建表“示例”。“数字”(
      `id` int(10) 无符号非空自动增量,
       主键(`id`)
    ) 引擎=InnoDB 默认字符集=latin1;
    
  2. 使用以下方式填充表:

    插入数字
      (ID)
    价值观
      (无效的)
    

    ...您需要的任意数量的值。

  3. 使用DATE_ADD 构建日期列表,根据 NUMBERS.id 值增加天数。将“2010-01-01”和“2010-01-02”替换为各自的开始日期和结束日期(但使用相同的格式,YYYY-MM-DD HH:MM:SS)。在此示例中,我从 CURRENT_DATE 中减去 NUMBERS.id 值,以获取上周的连续日期值列表 -

    <前><代码>选择 x.dt
    FROM (SELECT DATE_SUB(CURRENT_DATE, INTERVAL (n.id - 1) DAY) AS dt
    从数字 n
    其中 n.id <= 7 ) x

  4. 根据日期时间部分 LEFT JOIN 到数据表中。

    <前><代码>选择x.dt,
    COUNT(v.aid) AS 数量
    FROM (SELECT DATE_SUB(CURRENT_DATE, INTERVAL (n.id - 1) DAY) AS dt
    从数字 n
    其中 n.id <= 7 ) x
    左连接投票 v ON DATE(FROM_UNIXTIME(v.timestamp)) = DATE(x.dt)
    按 x.dt 分组
    按 x.dt 排序

为什么是数字而不是日期?

简单 - 可以根据数字生成日期,就像我提供的示例一样。它还意味着使用单个表,而不是每种数据类型一个表。

之前:

  SELECT DATE(FROM_UNIXTIME(v.timestamp)) AS dt,
         COUNT(v.aid)
    FROM VOTES v
   WHERE DATE(FROM_UNIXTIME(v.timestamp)) BETWEEN DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY)
                                              AND CURRENT_DATE
GROUP BY DATE(FROM_UNIXTIME(v.timestamp))

MySQL doesn't have recursive functionality, so you're left with using the NUMBERS table trick -

  1. Create a table that only holds incrementing numbers - easy to do using an auto_increment:

    DROP TABLE IF EXISTS `example`.`numbers`;
    CREATE TABLE  `example`.`numbers` (
      `id` int(10) unsigned NOT NULL auto_increment,
       PRIMARY KEY  (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    
  2. Populate the table using:

    INSERT INTO NUMBERS
      (id)
    VALUES
      (NULL)
    

    ...for as many values as you need.

  3. Use DATE_ADD to construct a list of dates, increasing the days based on the NUMBERS.id value. Replace "2010-01-01" and "2010-01-02" with your respective start and end dates (but use the same format, YYYY-MM-DD HH:MM:SS). In this example, I subtracted the NUMBERS.id value from the CURRENT_DATE to get a list of sequential date values for the last week -

    SELECT x.dt
      FROM (SELECT DATE_SUB(CURRENT_DATE, INTERVAL (n.id - 1) DAY) AS dt
              FROM numbers n
             WHERE n.id <= 7 ) x
    
  4. LEFT JOIN onto your table of data based on the datetime portion.

       SELECT x.dt,
               COUNT(v.aid) AS num
         FROM (SELECT DATE_SUB(CURRENT_DATE, INTERVAL (n.id - 1) DAY) AS dt
                 FROM numbers n
                WHERE n.id <= 7 ) x
    LEFT JOIN VOTES v ON DATE(FROM_UNIXTIME(v.timestamp)) = DATE(x.dt)
     GROUP BY x.dt
     ORDER BY x.dt
    

Why Numbers, not Dates?

Simple - dates can be generated based on the number, like in the example I provided. It also means using a single table, vs say one per data type.

Previously:

  SELECT DATE(FROM_UNIXTIME(v.timestamp)) AS dt,
         COUNT(v.aid)
    FROM VOTES v
   WHERE DATE(FROM_UNIXTIME(v.timestamp)) BETWEEN DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY)
                                              AND CURRENT_DATE
GROUP BY DATE(FROM_UNIXTIME(v.timestamp))
仙气飘飘 2024-10-05 01:04:04

可能想尝试将 varchar(20) 转换为 DATETIME,因为这就是您正在使用的。但对于过去 7 天,只需执行 WHERE timestamp > > @7天前。在你的解释中你说你使用unix时间戳,所以你需要从现在开始发送时间戳 - 7天。您还需要将默认值更改为 0,因为您所说的发送时间戳,而不是 DATETIME 值。

SELECT COUNT(*) 作为投票,援助来自表 WHERE 时间戳>@7DaysAgo GROUP BY 援助

might want to try converting your varchar(20) to a DATETIME, since that is what you are using anyways. But for the last 7 days just do WHERE timestamp > @7DaysAgo. In your explanation you said your using a unix timestamp, so u will need to send the timestamp from now - 7 days. You will also want to change your default to 0, since your sending timestamps you said, not DATETIME values.

SELECT COUNT(*) as votes, aid FROM table WHERE timestamp>@7DaysAgo GROUP BY aid

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文