我知道要在日期之前获得最接近的记录,我可以使用查询:
select *
from results
where resulttime = (select max(resulttime)
from results
where some_id = 15
and resulttime < '2012-07-27');
但我需要这样做一段时间,以便我知道每天最接近的记录。有什么想法吗?
这一系列日期将由generate_sequence()
生成。
最接近的先前记录可能是我们想要的值的前一天,但仍需要返回。
答案 0 :(得分:4)
应该是最简单的最快LEFT JOIN
和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;
结果(虚拟值):
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
我使用CTE来提供值,可以是表格或函数,也可以是unnested数组,也可以是使用generate_series()
生成的集合。 (你的意思是generate_series()
是“generate_sequence()”吗?)
首先我JOIN
搜索时间戳到表中所有行的前缀为resulttime
。我使用LEFT JOIN
代替JOIN
,以便在表中根本没有resulttime
时不会删除搜索时间戳。
将DISTINCT ON (x.search_ts)
与ORDER BY x.search_ts, r.resulttime DESC
结合使用时,我们得到的最大(或同等最大的)resulttime
小于或等于每个搜索时间戳。
答案 1 :(得分:1)
从类似于您的示例的时间序列中识别日间边界内的最大日期的简单子查询将是这样的
SELECT max(resulttime), date_trunc('days',resulttime) FROM results GROUP BY 2;
使用date_trunc函数将时间戳固定到day组件,然后使用GROUP BY max()
收集每个截断日期的最大时间戳