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

Enregistrement le plus proche pour une série de dates

Devrait être plus simple et plus rapide avec un LEFT JOIN et DISTINCT ON :

WITH x(search_ts) AS (
    VALUES
     ('2012-07-26 20:31:29'::timestamp)              -- search timestamps
    ,('2012-05-14 19:38:21')
    ,('2012-05-13 22:24:10')
    )
SELECT DISTINCT ON (x.search_ts)
       x.search_ts, r.id, r.resulttime
FROM   x
LEFT   JOIN results r ON r.resulttime <= x.search_ts -- smaller or same
-- WHERE some_id = 15                                -- some condition?
ORDER  BY x.search_ts, r.resulttime DESC;

Résultat (valeurs factices) :

search_ts           | id     | resulttime
--------------------+--------+----------------
2012-05-13 22:24:10 | 404643 | 2012-05-13 22:24:10
2012-05-14 19:38:21 | 404643 | 2012-05-13 22:24:10
2012-07-26 20:31:29 | 219822 | 2012-07-25 19:47:44

J'utilise un CTE pour fournir les valeurs, il peut s'agir d'une table ou d'une fonction ou d'un tableau non imbriqué ou d'un ensemble généré avec generate_series() autre chose aussi. (Voulez-vous dire generate_series() par "generate_sequence()" ?)

D'abord je JOIN les horodatages de recherche de toutes les lignes de la table avec resulttime antérieur ou égal . J'utilise LEFT JOIN au lieu de JOIN afin que les horodatages de recherche ne soient pas supprimés lorsqu'il n'y a pas de resulttime précédent dans le tableau.

Avec DISTINCT ON (x.search_ts) en combinaison avec ORDER BY x.search_ts, r.resulttime DESC nous obtenons le plus grand (ou l'un des plus grands) resulttime qui est inférieur ou égal à chaque horodatage de recherche.