我有一个包含值和时间戳的行的表。只要值发生更改,就会插入一行,时间戳指示更改发生的时间。例如,像这样:
id | value | timestamp
-----+-------+----------------------------
1 | 736 | 2014-03-18 16:38:22.20548
2 | 531 | 2014-06-18 16:38:22.664324
3 | 24 | 2014-07-18 16:38:22.980137
4 | 530 | 2014-09-22 10:01:36.13856
5 | 529 | 2014-09-23 10:01:27.202026
我需要Postgresql中的一个查询,它会为一年中的每个月生成一行表。每行都有一个时间戳(每月的第一天)和一个值。该值是在给定月份开始之前插入的第一个表的最后一个值。如果第一个表中没有匹配的行,则该值应为0。像这样:
id | value | timestamp
-----+-------+----------------------------
1 | 0 | 2014-01-01 00:00:00.000000
2 | 0 | 2014-02-01 00:00:00.000000
3 | 0 | 2014-03-01 00:00:00.000000
4 | 736 | 2014-04-01 00:00:00.000000
5 | 736 | 2014-05-01 00:00:00.000000
6 | 736 | 2014-06-01 00:00:00.000000
7 | 531 | 2014-07-01 00:00:00.000000
8 | 24 | 2014-08-01 00:00:00.000000
9 | 24 | 2014-09-01 00:00:00.000000
10 | 529 | 2014-10-01 00:00:00.000000
11 | 529 | 2014-11-01 00:00:00.000000
12 | 529 | 2014-12-01 00:00:00.000000
我尝试了一段时间,但我没有设法得到完整的结果。我想我需要生成这样的月份列表。
SELECT
*
FROM
generate_series('2014-01-01 00:00'::timestamp, now(), '1 month') AS months
然后做一些这样的事情来获得一个月前的最后一次出现:
SELECT
*
FROM first_table
WHERE timestamp < --current_month_selection--
ORDER BY timestamp desc
LIMIT 1;
我想我需要一个OUTER JOIN和一个CASE条件...... 不幸的是,我没有把它放在一起。有人可以帮帮我吗?
答案 0 :(得分:1)
实际上,我认为我自己解决了这个问题,这非常简单:
SELECT
month,
COALESCE((SELECT value
FROM first_table
WHERE timestamp < month
ORDER BY timestamp DESC
LIMIT 1),0)
FROM
generate_series('2014-01-01 00:00'::timestamp, now(), '1 month') AS month