sql >> Base de Datos >  >> RDS >> PostgreSQL

Registro más cercano para una serie de fechas

Debería ser más simple y rápido con LEFT JOIN y 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;

Resultado (valores ficticios):

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

Uso un CTE para proporcionar los valores, podría ser una tabla, una función, una matriz no anidada o un conjunto generado con generate_series() algo más también. (¿Quiso decir generate_series()? por "generar_secuencia()"?)

Primero me JOIN las marcas de tiempo de búsqueda en todas las filas de la tabla con resulttime anterior o igual . Yo uso LEFT JOIN en lugar de JOIN para que las marcas de tiempo de búsqueda no se eliminen cuando no hay un resulttime anterior en la tabla en absoluto.

Con DISTINCT ON (x.search_ts) en combinación con ORDER BY x.search_ts, r.resulttime DESC obtenemos el mejor (o uno de los mejores) resulttime que es menor o igual a cada marca de tiempo de búsqueda.