sql - 最近 7 天的 MySQL 计数数据

标签 sql mysql datetime-generation

我有以下架构。

表票

+------------------+--------------+------+-----+---------------------+----------------+
| 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”表示没有援助投票的日期。 timestamp 这里是unix时间戳。

非常感谢任何帮助。

最佳答案

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

  1. 创建一个只包含递增数字的表 - 使用 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. 使用以下方法填充表格:

    INSERT INTO NUMBERS
      (id)
    VALUES
      (NULL)
    

    ...根据您的需要获取尽可能多的值。

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

    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. 根据日期时间部分左连接到您的数据表。

       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
    

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

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

之前:

  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))

关于sql - 最近 7 天的 MySQL 计数数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3954200/

相关文章:

mysql - 从多个表的变量进行查询

sql - 如何在 MySQL 中创建秒列表

SQL:将整行数据与数字进行比较

sql - Access SQL 似乎将日期视为 dd/mm/yyyy?

sql - Elixir PostgreSQL - 选择查询返回不符合 WHERE 子句的结果

sql - mysql 动态变量

mysql - 使用mysql选择数据

mysql - 在 WHERE 子句中访问 SELECT 的计算值

sql - SQL查询-在12小时内选择重复项

mysql - NODEJS - 执行 INNER JOIN Sequelize