【问题标题】:MySQL Average Every 4 RowsMySQL 平均每 4 行
【发布时间】:2011-08-09 14:29:55
【问题描述】:

我有一个超过 1000 万行的表格,如下所示:

    id | time_read  | value
    -----------------------
    9   1111111111   100
    9   1111111222   200
    9   1111111333   150
    9   1111111444   225

我想平均每 4 行的值。如何在 MySQL 中执行此操作?

另外,对于我的问题,如果我想对一个月内所有数据的每 4 行的值进行平均,并在表中返回每年每个月的总数,我该怎么做?例如,在我的第一个问题中使用同一张表,结果是:

    2008 | 12 | 500000
    2009 | 01 | 450000
    2009 | 02 | 475000

edit:换句话说,每个平均 4 行的总和按年月分组。每个 time_read 相隔 15 分钟。

我以前做过类似的事情,但不够准确。我需要对每 4 行取平均值并将其总计,而不是取一个月内所有值的总和除以 4。

    SELECT DATE_FORMAT(FROM_UNIXTIME(time_read),'%Y %m') as tr,  
    DATE_FORMAT(FROM_UNIXTIME(time_read),'%Y') as year, 
    DATE_FORMAT(FROM_UNIXTIME(time_read),'%m') as month, SUM(value) as value 
    FROM table WHERE id = 9 
    GROUP BY tr

【问题讨论】:

  • id是否每四行改变一次?
  • 每四行?你想如何订购清单? id 是连续的吗?
  • id 不会每四行改变一次。一步一步地,我想获取单个 id 的所有记录。从这些记录中,我想平均每 4 行一个月。我的最终表格将包含数据库中每个月/年的这些平均值的总数。 time_read 字段是一个 unix 时间戳。
  • 您确定要在数据库中执行此操作吗?似乎从数据库中提取所有值并以通用编程语言进行平均会更容易(而且不会更重)。
  • 也可以。在那种情况下,我会做一些类似于 OP 中的查询的事情,只是没有 GROUP BY 和 SUM。不过,这将是一个巨大的结果集……在某些情况下,有一百万条记录。

标签: php mysql


【解决方案1】:

如果您不想依赖“id”列(它可能不是连续的),您可以创建自己的变量以按每 4 行更改一次进行分组,如下所示:

SET @rank = 0;
SELECT AVG(value), CEIL((@rank:=@rank+1)/4) AS rank FROM "your_table" GROUP BY rank;

【讨论】:

    【解决方案2】:

    我不知道您是否故意这样做,但我认为这只是一个小错字:您的 ID 是每行的 9。
    如果是,您可能正在寻找以下查询:

    SELECT AVG(value) AS val, CEIL(id / 4) AS group_id FROM table GROUP BY group_id
    

    第二个问题:

    SELECT SUM(val) FROM (SELECT AVG(value) AS val, CEIL(id / 4) AS group_id FROM table GROUP BY group_id) AS fred
    

    目前我无法为第二个问题提供where-part,因为我不知道您如何按日期过滤内容(我没有看到日期列或其他内容)。所以现在,这将计算由 4 分组的所有平均 values 中的 sum

    【讨论】:

    • 遗憾的是,根据 OP 的最新评论,ID 看起来根本没有改变 :( 我认为他们正在寻找按 time_read 排序的每 4 行。跨度>
    【解决方案3】:

    试试这个代码 -

    CREATE TABLE table1 (
      id INT(11) NOT NULL AUTO_INCREMENT,
      time_read INT(11) DEFAULT NULL,
      value INT(11) DEFAULT NULL,
      PRIMARY KEY (id)
    );
    
    INSERT INTO table1 VALUES 
      (1, 1312880400, 10),  -- 09.08.2011 12:00:00 -> 1 august
      (2, 1312880410, 20),  -- 09.08.2011 12:00:10 -> 2
      (3, 1312880420, 30),  -- 09.08.2011 12:00:20 -> 3
      (4, 1312880430, 40),  -- 09.08.2011 12:00:30 -> 4
      (5, 1312880440, 50),  -- 09.08.2011 12:00:40 -> 5
      (6, 1315558800, 60),  -- 09.09.2011 12:00:00 -> 1 september
      (7, 1315558810, 70);  -- 09.09.2011 12:00:10 -> 2
    
    SELECT AVG(value) FROM (
      SELECT t1.*, COUNT(*) cnt FROM table1 t1
      LEFT JOIN table1 t2
        ON t2.time_read <= t1.time_read
          AND YEAR(FROM_UNIXTIME(t2.time_read)) = YEAR(FROM_UNIXTIME(t1.time_read))
          AND MONTH(FROM_UNIXTIME(t2.time_read)) = MONTH(FROM_UNIXTIME(t1.time_read))
      GROUP 
        BY time_read
    ) t
    GROUP BY
      YEAR(FROM_UNIXTIME(time_read)), MONTH(FROM_UNIXTIME(time_read)), CEIL(cnt/4);
    
    +------------+
    | AVG(value) |
    +------------+
    |    25.0000 |
    |    50.0000 |
    |    65.0000 |
    +------------+
    

    它确实按月分组,每个月有 4 条记录。

    【讨论】:

    • 不是我想要的(每月 1 个值,该月平均小时数(每 4 行 1 个)),但我能够让它工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多