2013-09-24 40 views
0

我希望能夠創建一個函數,它接受一個「標準化」查詢集,該查詢集具有整數id字段和時間戳作爲列,然後修改查詢集按每個30分鐘塊中的數量進行計數。下面的代碼適用於30分鐘的塊,如果你用真正的查詢替換Q並執行WITH(QUERY)Q.但是我希望能夠傳入任何適合該類型的查詢,然後返回新的SETOF range_durations_type。Postgres函數,需要一個時間間隔並返回一個結果集

CREATE TYPE range_durations_type AS (dtime TIMESTAMP, counts BIGINT); 
CREATE TYPE object_datetime AS (id INTEGER, dtime TIMESTAMP); 

CREATE OR REPLACE FUNCTION time_range_durations(Q range_durations_type, start_date TIMESTAMP, end_date TIMESTAMP) 
    RETURNS SETOF range_durations_type AS $$ 
BEGIN 

    RETURN QUERY WITH q_cleaned AS (
    SELECT 
     Q.id, 
     Q.dtime, 
     Q.dtime - (
        (extract(EPOCH FROM Q.dtime :: TIMESTAMP)) :: INTEGER - 
        extract(EPOCH FROM Q.dtime :: TIMESTAMP) :: INTEGER/1800 * 1800 
       ) * INTERVAL '1 second' AS rounded_dtime 
    FROM Q 
) 
       SELECT 
       series.dtime, 
       count(q_cleaned.id) 
       FROM (
         SELECT 
         * 
         FROM 
         generate_series(start_date, end_date, '30 minutes') dtime) series 
       LEFT JOIN q_cleaned ON series.dtime = q_cleaned.rounded_dtime 
       GROUP BY 1 
       ORDER BY 1; 

END; 
$$ LANGUAGE plpgsql; 
+0

OT,但是......你知道Postgres有範圍類型,對嗎? http://www.postgresql.org/docs/current/static/rangetypes.html –

+0

是的,我一直在經歷的類型,看看他們中的任何一個會工作。我對他們不夠熟悉......感謝提示。 – hazmat

回答

0

我認爲一個完整的解決方案將超越這裏的一個單一的答案,但有幾個重要的部分,我會建議直接看。

  1. 範圍類型。在我看來,你正在尋找一組間隔。這將允許你做這樣的事情:

    CREATE OR REPLACE FUNCTION time_range_durations(bounds rsrange, inc interval) 
    

    ,這將允許你這樣做非常不同的東西,即一個範圍,並且可以用來在它增加的間隔。所以你可以在兩個時間戳內以任意的增量來看待事物。

  2. 然後,您可以將inc傳遞給您的generate_series函數。

相關問題