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

Como rotular grupos no postgresql quando o pertencimento ao grupo depende da linha anterior?


Uma "selecionar dentro de uma seleção" é mais comumente chamado de "subseleção" ou "subconsulta" No seu caso específico, é uma subconsulta correlacionada . LATERAL joins (novo no postgres 9.3) pode substituir em grande parte subconsultas correlacionadas por soluções mais flexíveis:

Acho que você também não precisa aqui.

Para seu primeiro caso esta consulta é provavelmente mais rápida e simples, no entanto:
SELECT date, max(value) OVER (PARTITION BY grp) AS value
FROM  (
   SELECT *, count(value) OVER (ORDER BY date) AS grp
   FROM   test_fill_null
   ) sub;

count() conta apenas valores não nulos, então grp é incrementado com cada value não nulo , formando assim grupos conforme desejado. É trivial escolher o um value não nulo por grp no SELECT externo .

Para seu segundo caso , assumirei que a ordem inicial das linhas é determinada por (id1, id2, tms) conforme indicado por uma de suas perguntas.
SELECT id1, id2, tms
     , count(step) OVER (ORDER BY id1, id2, tms) AS group_id
FROM  (
   SELECT *, CASE WHEN lag(tms, 1, '-infinity') OVER (PARTITION BY id1 ORDER BY id2, tms)
                       < tms - interval '5 min'
                  THEN true END AS step
   FROM   table0
   ) sub
ORDER  BY id1, id2, tms;

Adapte-se ao seu pedido real. Um deles pode cobri-lo:
PARTITION BY id1 ORDER BY id2  -- ignore tms
PARTITION BY id1 ORDER BY tms  -- ignore id2

SQL Fiddle com um exemplo estendido.

Relacionado: