我運行的Postgres 9.2和我有一個大的表像滾動平均的Postgres
CREATE TABLE sensor_values
(
ts timestamp with time zone NOT NULL,
value double precision NOT NULL DEFAULT 'NaN'::real,
sensor_id integer NOT NULL
)
我進入系統的價值不斷地即多每分鐘。我想維持最後200個值的滾動標準偏差/平均值,因此我可以確定進入系統的新值是否在平均值的3個標準偏差之內。要做到這一點,我需要當前的標準偏差和意思是不斷更新最後200個值。 由於表格可能有數億行,我不想最後說200行的傳感器按時間排序,然後對每個新值進行vg(value),var_samp(value)。我假設更新標準偏差和平均值會更快。
我已經開始編寫一個PL/pgSQL函數來更新每個進入特定傳感器系統的新值的滾動方差和平均值。
我可以做到這一點使用碼僞像
newavg = oldavg + (new_value - old_value)/window_size
new_variance += (new_value-old_value)*(new_value-newavg+old_value-oldavg)/(window_size-1)
這是基於 http://jonisalonen.com/2014/efficient-and-accurate-rolling-standard-deviation/
基本上窗口大小200個的值。 old_value是窗口的第一個值。當有新的價值出現時,我們將窗口向前移動一個。之後,我得到的結果我存儲以下值傳感器
The first value of the window.
The mean average of the window values.
The variance of the window values.
這樣我就不必不斷那裏持續200價值,做一個總和etc.I可以重複使用這個值時,一個新的傳感器值進來
我的問題是,當第一次運行我沒有一個傳感器的前一個窗口數據,即上述三個值,所以我必須做的慢的方式。
像
WITH s AS
(SELECT value FROM sensor_values WHERE sensor_values.sensor_id = $1 AND ts >= (NOW() - INTERVAL '2 day')::timestamptz ORDER BY ts DESC LIMIT 200)
SELECT avg(value), var_samp(value) INTO last_window_average, last_window_variance FROM s;
但我怎麼能得到最後的值(ealiest),以從select語句救? 我可以在PL/pgSQL中訪問s中的第一行嗎?
我認爲PL/pgSQL會更快/更乾淨的方法,但也許它更好地做到這一點是客戶端代碼? 有沒有更好的方法在滾動統計更新上執行此類型?
什麼'AVG(值)超過(前述200之間分區由sensor_id爲了通過TS行和當前行)作爲avg' –