将 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
我有一个 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