PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Genera_series in Postgres dalla data di inizio e fine in una tabella

Non è necessario un CTE per questo, sarebbe più costoso del necessario.
E non è necessario eseguire il cast su timestamp , il risultato è già è di tipo di dati timestamp quando inserisci timestamp digita su generate_series() . Dettagli qui:

  • Generazione di serie temporali tra due date in PostgreSQL

In Postgres 9.3 o successivamente puoi usare un LATERAL unisciti:

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

Facoltativamente con to_char() per ottenere il risultato come testo nel formato da te indicato.

Funziona in qualsiasi Versione Postgres:

SELECT generate_series(min(start_timestamp)
                     , max(start_timestamp)
                     , interval '1 hour') AS ts
FROM   header_table;

In genere un po' più veloce.
Richiamare le funzioni di restituzione dei set in SELECT list è una funzionalità SQL non standard e disapprovata da alcuni. Inoltre, c'erano stranezze comportamentali (anche se non per questo semplice caso) che alla fine sono state risolte in Postgres 10. Vedi:

  • Qual ​​è il comportamento previsto per più funzioni di restituzione di set nella clausola SELECT?

Nota una sottile differenza in NULL gestione:

L'equivalente di

max(start_timestamp)

si ottiene con

ORDER BY start_timestamp DESC NULLS LAST
LIMIT 1

Senza NULLS LAST I valori NULL vengono prima in ordine decrescente (se può essere valori NULL in start_timestamp ). Otterresti NULL per last_date e la tua domanda risulterebbe vuota.

Dettagli:

  • Perché i valori NULL vengono prima quando si ordina DESC in una query PostgreSQL?