0

我希望能够创建一个函数,该函数接受一个“标准化”查询集,该查询集具有一个整数 id 字段和一个时间戳作为列,然后修改查询集以按计数聚合每 30 分钟块中的数字。如果您将 Q 替换为实际查询并执行 WITH (QUERY) Q,则下面的代码可以工作 30 分钟。但我希望能够传入任何适合该类型的查询,然后取回新的 SETOF range_durations_type。

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;
4

1 回答 1

0

我认为一个完整的解决方案将不仅仅是一个单一的答案,但我建议直接查看几个重要的部分。

  1. 范围类型。在我看来,您正在寻找一组间隔。这将允许您执行以下操作:

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

    这将允许您做一些非常不同的事情,即范围和可用于在其中递增的间隔。因此,您可以通过任意增量查看两个时间戳内的事物。

  2. 然后,您可以将 inc 传递给您的 generate_series 函数。

于 2013-11-22T04:37:20.477 回答