如果您希望结果中有多个这样的行,我会使用一个crosstab()
函数。
但根据你的描述,你想要一个单行。我会用窗口函数lead()
或lag()
.
主要技巧是在应用 WHERE 子句并将结果缩小到单行之前使用子查询或 CTE 生成所有列。我会在这里使用CTE:
给定下表(您应该提供):
CREATE TABLE tbl(
tbl_id serial PRIMARY KEY
,ts timestamp NOT NULL
,value int
);
保证每天一排
查询可能如下所示:
WITH x AS (
SELECT tbl_id, ts, value
,lag(value, 1) OVER w AS value_day_before_1
,lag(value, 2) OVER w AS value_day_before_2
-- ...
,lead(value, 1) OVER w AS value_day_after_1
,lead(value, 2) OVER w AS value_day_after_2
-- ...
FROM tbl
WINDOW w AS (ORDER BY ts)
)
SELECT *
FROM x
WHERE ts = '2013-02-14 0:0'::timestamp
每天最多一行,但可能缺少天数:
时间戳也可以是一天中的任何时间。
生成一个日期列表generate_series()
和LEFT JOIN
你的表格:
WITH x AS (
SELECT tbl_id, ts, value
,lag(value, 1) OVER w AS value_day_before_1
,lag(value, 2) OVER w AS value_day_before_2
-- ...
,lead(value, 1) OVER w AS value_day_after_1
,lead(value, 2) OVER w AS value_day_after_2
-- ...
FROM (
SELECT generate_series ('2013-02-01'::date
,'2013-02-28'::date
,interval '1d') AS day
) d
LEFT JOIN tbl t ON date_trunc('day', t.ts) = d.day
WINDOW w AS (ORDER BY day)
)
SELECT *
FROM x
WHERE ts = '2013-02-14 0:0'::timestamp;
-> sqlfiddle