Deve ser mais simples e rápido com um
LEFT JOIN
e 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 fictícios):
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
Eu uso um CTE para fornecer os valores, pode ser uma tabela ou função ou array não aninhado ou um conjunto gerado com
generate_series()
outra coisa também. (Você quis dizer generate_series()
por "generate_sequence()"?) Primeiro eu
JOIN
os carimbos de data e hora de pesquisa para todas as linhas na tabela com resulttime
anterior ou igual . Eu uso LEFT JOIN
em vez de JOIN
para que os carimbos de data e hora de pesquisa não sejam descartados quando não houver resulttime
anterior na mesa em tudo. Com
DISTINCT ON (x.search_ts)
em combinação com ORDER BY x.search_ts, r.resulttime DESC
obtemos o maior (ou um dos igualmente maiores) resulttime
que é menor ou igual a cada timestamp de pesquisa.