2009-06-02 115 views
3

問題:過的日期/時間段計算平均值

我有傳感器讀數與用於傳感器讀取的時間的時間戳的數據庫。基本上看起來像這樣:

Sensor | Timestamp | Value 

現在我想從這些數據中製作一個圖表,並且我想製作幾個不同的圖表。假設我想在最後一天得到一個,最後一個星期要一個,最後一個月要一個。每張圖的分辨率會有所不同,因此對於日圖,分辨率將爲1分鐘。對於星期圖,它將是一個小時,對於月份圖,它將是一天或四分之一天。

所以想的輸出即每個分辨率(例如天=平均過分鐘,周=平均過小時等。)的平均

例:

Sensor | Start | End | Average 

我如何在mySQL中輕鬆快捷地完成此操作?我懷疑它是否會創建一個臨時表或者分類並加入傳感器數據以獲得傳感器的平均值?但是我對mySQL的瞭解還是有限的。

有沒有一個真正聰明的方法來做到這一點?

回答

7
SELECT DAY(Timestamp), HOUR(Timestamp), MINUTE(Timestamp), AVG(value) 
FROM mytable 
GROUP BY 
     DAY(Timestamp), HOUR(Timestamp), MINUTE(Timestamp) WITH ROLLUP 

WITH ROLLUP條款產生與每個HOURDAY,這樣平均額外行:

SELECT DAY(ts), HOUR(ts), MINUTE(ts), COUNT(*) 
FROM (
     SELECT CAST('2009-06-02 20:00:00' AS DATETIME) AS ts 
     UNION ALL 
     SELECT CAST('2009-06-02 20:30:00' AS DATETIME) AS ts 
     UNION ALL 
     SELECT CAST('2009-06-02 21:30:00' AS DATETIME) AS ts 
     UNION ALL 
     SELECT CAST('2009-06-03 21:30:00' AS DATETIME) AS ts 
     ) q 
GROUP BY 
     DAY(ts), HOUR(ts), MINUTE(ts) WITH ROLLUP 
 
2, 20, 0, 1 
2, 20, 30, 1 
2, 20, NULL, 2 
2, 21, 30, 1 
2, 21, NULL, 1 
2, NULL, NULL, 3 
3, 21, 30, 1 
3, 21, NULL, 1 
3, NULL, NULL, 1 
NULL, NULL, NULL, 4 

這裏的表示COUNT(*)2DAY = 2HOUR = 20和所有分鐘。

+0

這產生的東西接近我期待的結果。 「WITH ROLLUP」做了什麼,因爲它看起來會產生相同的結果,如果我刪除它? – 2009-06-02 16:51:41

+1

來自MySQL參考手冊: 「向GROUP BY子句添加WITH ROLLUP修飾符會導致查詢產生另一行,顯示所有值的總數」 – nightcoder 2009-06-02 16:54:29

2

不太結果表你想要的,但在這裏是做1分鐘的分辨率首發:這裏

SELECT sensor,minute(timestamp),avg(value) 
FROM table 
WHERE <time period specifier limits to a single hour> 
GROUP BY sensor, minute(timestamp) 
2

我使用的代碼非常相似,這種(未經測試,但它從工作中採取)

設置的變量:

$seconds = 3600; 
$start = mktime(...); // say 2 hrs ago 
$end = .... // 1 hour after $start 

然後運行查詢

SELECT MAX(`when`) AS top_When, MIN(`when`) AS low_When, 
    ROUND(AVG(sensor)) AS Avg_S, 
    (MAX(`when`) - MIN(`when`)) AS dur, /* the duration in seconds of the actual period */ 
    ((floor(UNIX_TIMESTAMP(`when`)/$seconds)) * $seconds) as Epoch 
    FROM `sensor_stats` 
    WHERE `when` >= '$start' AND `when` <= '$end' and duration=30 
    GROUP BY Epoch/*((floor(UNIX_TIMESTAMP(`when`)/$seconds)) * $seconds)*/ 

的這樣做的好處是你可以有任何你想要的時間段 - 甚至不需要讓他們在「整數」上,比如一個完整的時鐘小時(即使是一個鐘點,0-59)。