рассчитать средние для 5-минутных интервалов в MySQL - PullRequest
2 голосов
/ 02 ноября 2010

У меня есть таблица log с столбцами id, значением, категорией и отметкой времени. Предположим, что таблица заполнена так:

ID   VALUE        CATEGORY   TIMESTAMP
-----------------------------------------------
1     10             1       2010-11-1 10:00:00
2     20             1       2010-11-1 10:03:00
3     15             2       2010-11-1 10:15:00
4     05             2       2010-11-1 10:19:00
5     30             1       2010-11-1 10:24:00
6     12             1       2010-11-1 10:30:00

Теперь я хотел бы создать таблицу с avg () для значения столбца с 5-минутными интервалами для указанной проверки, начиная с последней записи проверки. Выход для check = 1 должен быть таким:

ID AVERAGE
----------
1  12
2  30
3  15

вывод для check = 2 должен быть таким:

ID AVERAGE
----------
1  10

Как лучше всего подойти к этому? У меня есть базовые знания MySQL, но это меня озадачивает. Я полагаю, что часть запроса будет выглядеть так (без группировки с 5-минутным интервалом):

SELECT avg(value) FROM log WHERE check = ..

Как я могу использовать временные метки для получения 5-минутных средних значений? Любая помощь с благодарностью.

Ответы [ 4 ]

1 голос
/ 02 ноября 2010

См. это .

select AVG(value),  from_unixtime(ROUND(timestamp / (60*5)) * 60 * 5) as rounded_time
from table
group by rounded_time
0 голосов
/ 02 декабря 2013
SELECT 
   DATE_FORMAT((atimestamp),
      concat( '%Y-%m-%d %H:' , 
            cast(round(minute(atimestamp)) -  round(minute(atimestamp)) % 5 as char))
   )AS rounded_time
   ,avg(price) , count(*) from table

Таким образом, вы можете получить 5, 10, 15, 30etc. средняя минута легко.

0 голосов
/ 08 ноября 2011

Возможно позже, но самый короткий запрос будет:

 SELECT ID, AVG(VALUE) as average, DATE_FORMAT(MIN(timestamp), '%Y-%m-%d %H:%i:00') AS tmstamp
   FROM yourtable GROUP BY round(UNIX_TIMESTAMP(timestamp) DIV 60*5)
0 голосов
/ 05 ноября 2010

Если кто-то еще заинтересован, вот ответ, который я придумаю (с помощью коллеги).

Сначала создайте хранимую процедуру в MysQL следующим образом (исходный код изменен здесь http://ondra.zizka.cz/stranky/programovani/sql/mysql_stored_procedures.texy):

DELIMITER $$
CREATE PROCEDURE generate_series (
  iFrom TIMESTAMP, iTo TIMESTAMP, iStep INTEGER )

body:
BEGIN

  DROP TEMPORARY TABLE IF EXISTS stamp_series;
  CREATE TEMPORARY TABLE stamp_series ( stamp TIMESTAMP NOT NULL);

  IF iFrom IS NULL OR iTo IS NULL OR iStep IS NULL
    THEN LEAVE body; END IF;

  SET @iMax = iFrom;
  SET @iMin = iTo;

  InsertLoop: LOOP
    INSERT INTO stamp_series SET stamp = @iMax;
    SET @iMax = DATE_SUB( @iMax, INTERVAL iStep SECOND);
    IF @iMin > @iMax THEN LEAVE InsertLoop; END IF;
  END LOOP;

END; $$
DELIMITER ;

тогда фактический запрос выглядит так:

CALL generate_series( timestamp1 , timestamp2 , 300);
SELECT stamp, DATE_SUB(stamp, INTERVAL 5 MINUTE) AS stamp_min_5, (  SELECT COALESCE( AVG(value), 0) FROM `table` WHERE `category` = 1 AND timestamp <= stamp AND timestamp > DATE_SUB(stamp, INTERVAL 5 MINUTE) ) AS gem FROM stamp_series; 

С уважением, Ivo

...