2010-11-01 314 views
2

我有一個表log,其中有列id,值,類別和時間戳。假設表充滿這樣的:在mysql中計算5分鐘間隔的平均值

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 

現在我想在5個分鐘爲間隔的AVG()的列值生成一個表指定的檢查,從最後的檢查條目開始。對於檢查= 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分鐘的平均值?任何幫助是極大的讚賞。

+0

我不知道mysql,但從看看GROUP BY是做什麼開始的。 – Pointy 2010-11-01 21:37:43

+1

你能解釋一下'check = 1'的功能嗎?我沒有得到這部分。 – 2010-11-01 21:44:11

+0

check = 1僅表示列值爲1的列檢查的平均間隔時間爲5分鐘 – Ivo 2010-11-01 21:51:29

回答

1

參見this

select AVG(value), from_unixtime(ROUND(timestamp/(60*5)) * 60 * 5) as rounded_time 
from table 
group by rounded_time 
+0

這幾乎讓我在那裏!我應該提到時間戳採用日期時間格式,因此:從'log'中選擇AVG(值),from_unixtime(ROUND(unix_timestamp(timestamp)/(60 * 5))* 60 * 5)作爲rounded_time,其中'check' = round_time的1組幾乎讓我在那裏。我希望5分鐘的間隔從特定檢查的最後時間戳記條目開始,而不是00,05,10等。例如,檢查2間隔期應該是10:19,10:14等。 – Ivo 2010-11-01 22:07:20

+0

@Ivo:可能類似於'set @ min_1:= min(from_unixtime ...'然後在你的選擇做'... ROUND((timestamp + @ min_1)/(60 * 5)...' – Xodarap 2010-11-02 01:09:00

0

如果別人有興趣,這裏是我提出的答案(在同事的幫助下)。

首先在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; 

問候, 伊沃

0

也許稍後,但最短的查詢將是:

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
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,30等等。分鐘平均容易。