PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

MySQL/Postgres consulta dados de intervalo de 5 minutos

CTE recursiva


Como cada linha depende da anterior, é difícil resolver com uma abordagem baseada em conjuntos. Recorrendo a um CTE recursivo (que é SQL padrão):
WITH RECURSIVE cte AS (
   (SELECT ts FROM tbl
    ORDER  BY ts
    LIMIT  1)

   UNION ALL
   (SELECT t.ts
    FROM   cte c
    JOIN   tbl t ON t.ts >= c.ts + interval '5 min'
    ORDER  BY t.ts
    LIMIT  1)
   )
SELECT * FROM cte ORDER BY ts;

Observe a atualização do meu primeiro rascunho:
Funções agregadas não são permitidas em uma CTE recursiva. Substituí por ORDER BY / LIMIT 1 , que deve ser rápido quando suportado por um índice em ts .

Os parênteses em torno de cada perna do UNION query são necessários para permitir LIMIT , que de outra forma só seria permitido uma vez no final de um UNION consulta.

Função PL/pgSQL


Uma solução procedural (exemplo com uma função plpgsql) iterando pela tabela classificada provavelmente seria muito mais rápida, pois pode se contentar com uma única varredura de tabela:
CREATE OR REPLACE FUNCTION f_rowgrid(i interval)
  RETURNS SETOF timestamp AS
$func$
DECLARE
   _this  timestamp;
   _last  timestamp := '-infinity';     -- init so that 1 row passes
BEGIN

FOR _this IN
    SELECT ts FROM tbl ORDER BY 1
LOOP
    IF _this >= _last + i THEN
       RETURN NEXT _this;
       _last := _this;
    END IF;
END LOOP;

END
$func$ LANGUAGE plpgsql;

Ligar:
SELECT * FROM  f_rowgrid('5 min')

SQL Fiddle demonstrando ambos.

Aqui está um exemplo um pouco mais complexo para este tipo de função plpgsql:

Poderia ser facilmente genérico com SQL dinâmico e EXECUTE para trabalhar para tabelas arbitrárias.