将 log table 转换为另一个 table,值分布在每个月

Transform log table into another table with values spread over every month

我有一个 table,其中的行由值和时间戳组成。只要值发生变化,就会插入一行,时间戳表示变化发生的时间。例如,像这样:

 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 中生成一个 table 查询,一年中的每个月都有一行。每行都有一个时间戳(每月的第一天)和一个值。该值是在给定月份开始之前插入的第一个 table 的最后一个值。如果第一个 table 中没有匹配的行,则该值应为 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 条件... 不幸的是我没有设法把它们放在一起。有人可以帮我吗?

其实,我想我自己解决了这个问题,这很简单:

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