2013-01-17 20 views
0

我有一個2分鐘採樣頻率的時態數據庫,我想提取瞬時小時值爲00:00,01:00,02,...每天23。
所以,我想獲得從平均值的平均值:根據PostgreSQL瞬時前後2分鐘創建小時平均值

HH-1:58,HH:00和HH:02 = HH點的平均

OR

HH-1:59,HH:01和HH:03 = HH點的平均

樣本數據1:

9/28/2007 23:51 -1.68 
9/28/2007 23:53 -1.76 
9/28/2007 23:55 -1.96 
9/28/2007 23:57 -2.02 
9/28/2007 23:59 -1.92 
9/29/2007 0:01 -1.64 
9/29/2007 0:03 -1.76 
9/29/2007 0:05 -1.83 
9/29/2007 0:07 -1.86 
9/29/2007 0:09 -1.94 

預期結果:

對於00午夜:

(-1.92 + -1.64 + -1.76)/ 3

樣本數據2:

9/28/2007 23:54 -1.44 
9/28/2007 23:56 -1.58 
9/28/2007 23:58 -2.01 
9/29/2007 0:00 -1.52 
9/29/2007 0:02 -1.48 
9/29/2007 0:04 -1.46 

預期結果:

(-2.01 + -1.52 + -1.48)/ 3

回答

1

PostgreSQL的window functions使涉及相鄰行的任何事情都比以前簡單得多。 02或:03前2個值2分鐘和4分鐘前, - :未試過,但應該大概就在最近值

select 
    date_trunc('hour', newest_time) as average_time, 
    (oldest_temp + middle_temp + newest_temp)/3 as average_temp 
from (
    select 
    date_trunc('hour', sample_time) as average_time, 
    lag(sample_time, 2) over w as oldest_time, 
    lag(sample_time, 1) over w as middle_time, 
    sample_time as newest_time, 
    lag(sample_temp, 2) over w as oldest_temp, 
    lag(sample_temp, 1) over w as middle_temp, 
    sample_temp as newest_temp 
    from 
    samples 
    window 
    w as (order by sample_time) 
) as s 
where 
    oldest_time = newest_time - '4 minutes'::interval and 
    middle_time = newest_time - '2 minutes'::interval and 
    extract(minute from newest_time) in (2, 3); 

我的where子句限制這正是你所描述的情況。以防萬一你有一些丟失的數據,否則會給出奇怪的結果,如平均時間更長。

+0

我想出了這個錯誤。 錯誤:在「over」處或附近的語法錯誤 SQL狀態:42601 字符:110 –

+0

試試這個版本,它爲我運行(儘管我還沒有放入任何數據來嘗試它)。這似乎是我誤解了一點點;它將範圍應用於單個「select」子句,而不是查詢中的每個窗口函數。我不確定是否可以將它應用到'where',所以我使用子查詢來完成。 –

+0

啊,從WHERE使用窗口函數是不可能的,因爲WHERE過濾首先發生:「窗口函數考慮的行是由查詢的FROM子句產生的」虛擬表「的行,由其WHERE,GROUP BY ,並且如果有的話有HAVING條款「。所以子查詢是必要的。 –

2
SELECT hr, ts, aval 
FROM (
     SELECT *, ROW_NUMBER() OVER (PARTITION BY hr ORDER BY ts) rn 
     FROM (
       SELECT *, 
         DATE_TRUNC('hour', ts) AS hr, 
         AVG(value) OVER (ORDER BY ts ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS aval 
       FROM mytable 
       ) q 
     ) q 
WHERE rn = 1