2013-09-24 38 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函数。

相关问题