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

Generate_series no Postgres da data de início e término em uma tabela


Você não precisa de um CTE para isso, isso seria mais caro do que o necessário.
E você não precisa transmitir para timestamp , o resultado já é do tipo de dados timestamp quando você alimenta timestamp tipos para generate_series() . Detalhes aqui:
  • Gerando séries temporais entre duas datas no PostgreSQL

No Postgres 9.3 ou mais tarde você pode usar um LATERAL Junte-se:
SELECT to_char(ts, 'YYYY-MM-DD HH24') AS formatted_ts
FROM  (
   SELECT min(start_timestamp) as first_date
        , max(start_timestamp) as last_date
   FROM   header_table
   ) h
  , generate_series(h.first_date, h.last_date, interval '1 hour') g(ts);

Opcionalmente com to_char() para obter o resultado como texto no formato que você mencionou.

Isso funciona em qualquer Versão do Postgres:
SELECT generate_series(min(start_timestamp)
                     , max(start_timestamp)
                     , interval '1 hour') AS ts
FROM   header_table;

Normalmente um pouco mais rápido.
Chamando funções de retorno de conjunto no SELECT list é um recurso SQL não padrão e desaprovado por alguns. Além disso, havia esquisitices comportamentais (embora não para este caso simples) que acabaram sendo corrigidas no Postgres 10. Veja:
  • Qual ​​é o comportamento esperado para várias funções de retorno de conjunto na cláusula SELECT?

Observação uma diferença sutil em NULL tratamento:

O equivalente de
max(start_timestamp)

é obtido com
ORDER BY start_timestamp DESC NULLS LAST
LIMIT 1

Sem NULLS LAST Valores NULL vêm primeiro em ordem decrescente (se houver pode ser valores NULL em start_timestamp ). Você obteria NULL para last_date e sua consulta ficaria vazia.

Detalhes:
  • Por que os valores NULL vêm primeiro ao ordenar DESC em uma consulta do PostgreSQL?