PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Generate_series dans Postgres à partir de la date de début et de fin dans une table

Vous n'avez pas besoin d'un CTE pour cela, ce serait plus cher que nécessaire.
Et vous n'avez pas besoin de caster en timestamp , le résultat est déjà est de type de données timestamp lorsque vous alimentez timestamp types à generate_series() . Détails ici :

  • Générer des séries temporelles entre deux dates dans PostgreSQL

Dans Postgres 9.3 ou plus tard, vous pouvez utiliser un LATERAL rejoindre :

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

Optionnellement avec to_char() pour obtenir le résultat sous forme de texte dans le format que vous avez mentionné.

Cela fonctionne dans tout Version postgres :

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

Typiquement un peu plus rapide.
Appel des fonctions de retour d'ensemble dans le SELECT list est une fonctionnalité SQL non standard et mal vue par certains. De plus, il y avait des bizarreries comportementales (mais pas pour ce cas simple) qui ont finalement été corrigées dans Postgres 10. Voir :

  • Quel est le comportement attendu pour plusieurs fonctions renvoyant des ensembles dans la clause SELECT ?

Remarque une différence subtile dans NULL traitement :

L'équivalent de

max(start_timestamp)

est obtenu avec

ORDER BY start_timestamp DESC NULLS LAST
LIMIT 1

Sans NULLS LAST Les valeurs NULL viennent en premier par ordre décroissant (s'il peut être des valeurs NULL dans start_timestamp ). Vous obtiendrez NULL pour last_date et votre requête serait vide.

Détails :

  • Pourquoi les valeurs NULL sont-elles prioritaires lors de l'ordre de DESC dans une requête PostgreSQL ?