2016-05-13 15 views
0

私たちはプロセスからのデータを記録するためにPostgresを使用します。次のように当社のデータベースの例は次のとおりです。Postgres時間平均データ

CREATE TABLE Data 
("time_stamp" timestamp, "pressure" numeric, "temperature" numeric, "flow" numeric); 

INSERT INTO Data 
("time_stamp", "pressure", "temperature", "flow") 
VALUES 
('2016-05-12 20:42:24', 97.68, 9.02564, 2.24664), 
('2016-05-12 20:42:25', 97.68, 9.02564, 2.24054), 
('2016-05-12 20:42:26', 122.1, 9.01832, 2.24054), 
('2016-05-12 20:42:27', 122.1, 9.01099, 2.23443), 
('2016-05-12 20:42:28', 97.68, 9.01099, 2.23443), 
('2016-05-12 20:42:29', 122.1, 9.01099, 2.24054), 
('2016-05-12 20:42:30', 97.68, 9.01099, 2.23443), 
('2016-05-12 20:42:31', 122.1, 9.01099, 2.23443), 
('2016-05-12 20:42:32', 122.1, 9.01832, 2.24054), 
('2016-05-12 20:42:33', 122.1, 9.01832, 2.23443); 

は、私は何をしようとしていることは、任意のタイムスライスの平均化されたデータを生成する(pgAdminIIIを使用して)のPostgresを取得している、5秒と言います。その5秒間のスライスの平均時間、圧力、温度、流れの欄を出力します。このデータには2つのエントリがあり、時刻エントリは '2016-05-12 20:42:26'と '2016-05-12 20:42:31'です。

答えて

0

これは最高の解決策ではありませんが、ちょっとしたことです。

SELECT timestamp without time zone '1970-01-01' + cast(avg(extract(epoch from time_stamp))::text as interval), 
     sub.press, 
     sub.temp, 
     sub.flow 
FROM data d join (
    SELECT 
      (extract(seconds from time_stamp)/5)::integer as num, 
      avg(pressure) as press, 
      avg(temperature) as temp, 
      avg(flow) as flow 
     FROM 
      data 
     group by 1) sub on sub.num=(extract(second from d.time_stamp)/5)::integer 
group by sub.press,sub.temp,sub.flow 
order by 1 

サブ選択は、データテーブルからデータを選択し、5秒間にグループ化します。外側の選択は、タイムスタンプが「平均化」されるために必要です。私は、これが関数ではるかに簡単であるべきだと思います。

編集: これは私がこれについて書いた機能です。毎秒1行しかないと仮定します。

CREATE TYPE t_data AS 
(
    time_stamp timestamp, 
    pressure numeric, 
    temp numeric, 
    flow numeric); 

これは、関数である:

CREATE OR REPLACE FUNCTION dataCheck (timeInterval integer) RETURNS setof t_data AS $BODY$ 
DECLARE 
    pressure numeric[]; 
    temp numeric[]; 
    flow numeric[]; 
    rec record; 
    i integer default 1; 
    ret t_data; 
BEGIN 
    for rec in select * from data order by time_stamp 
    loop 
    pressure[i]=rec.pressure; 
    temp[i]=rec.temp; 
    flow[i]=rec.flow; 

    if i=(timeInterval/2 + case when timeInterval%2 <> 0 then 1 else 0 end) then 
     ret.time_stamp=rec.time_stamp; 
    end if; 
    if i=timeInterval then 
     i=0; 
     ret.pressure=avg((select avg(a) from unnest(pressure) as a)); 
     ret.temp=avg((select avg(a) from unnest(temp) as a)); 
     ret.flow=avg((select avg(a) from unnest(flow) as a)); 
     return next ret; 
    end if; 

    i=i+1; 
    end loop; 

return ; 

end;$BODY$ LANGUAGE plpgsql; 

そして、これはあなたがそれを実行する方法である:

SELECT * from dataCheck(5); 

機能しますあなたが最初のカスタムタイプを作成する必要があり

「5」行ごとに平均化されたデータを戻す。

+0

どのような機能をお勧めしますか?コードを試しましたが、データセット全体でうまく動作しません。 – cshoopman

+0

私は関数で自分の答えを編集しました。 – perzsa

+0

昨日何らかの理由で私のデータ出力がちょうど毎秒ではなかったので、1日を通して25秒をスキップしました。このコードは毎秒エントリがないときにどのようにその状況を処理しますか? 私はdataCheck(300)WHERE TIME_STAMP :: DATE = 'YESTERDAY'; '関数を使って、これを昨日のデータファイルに適用しました。最初のタイムスタンプは平均して00:04:20になり、私はそれが00:02:30程度になると予想していました。 – cshoopman