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.