在 Postgresql 的时间序列数据中添加缺少的每月日期
Posted
技术标签:
【中文标题】在 Postgresql 的时间序列数据中添加缺少的每月日期【英文标题】:Add Missing monthly dates in a timeseries data in Postgresql 【发布时间】:2016-12-01 04:00:58 【问题描述】:我在表中有月度时间序列数据,其中日期是一个月的最后一天。数据中缺少某些日期。我想插入这些日期并为其他属性设置零值。 表如下:
id report_date price
1 2015-01-31 40
1 2015-02-28 56
1 2015-04-30 34
2 2014-05-31 45
2 2014-08-31 47
我想将此表转换为
id report_date price
1 2015-01-31 40
1 2015-02-28 56
1 2015-03-31 0
1 2015-04-30 34
2 2014-05-31 45
2 2014-06-30 0
2 2014-07-31 0
2 2014-08-31 47
有什么方法可以在 Postgresql 中做到这一点? 目前我们正在 Python 中执行此操作。由于我们的数据每天都在增长,而仅仅为一项任务处理 I/O 效率并不高。
谢谢
【问题讨论】:
【参考方案1】:您可以使用generate_series()
生成日期,然后使用left join
引入值:
with m as (
select id, min(report_date) as minrd, max(report_date) as maxrd
from t
group by id
)
select m.id, m.report_date, coalesce(t.price, 0) as price
from (select m.*, generate_series(minrd, maxrd, interval '1' month) as report_date
from m
) m left join
t
on m.report_date = t.report_date;
编辑:
事实证明上述方法不太适用,因为在月末添加月份并不能保留该月的最后一天。
这很容易解决:
with t as (
select 1 as id, date '2012-01-31' as report_date, 10 as price union all
select 1 as id, date '2012-04-30', 20
), m as (
select id, min(report_date) - interval '1 day' as minrd, max(report_date) - interval '1 day' as maxrd
from t
group by id
)
select m.id, m.report_date, coalesce(t.price, 0) as price
from (select m.*, generate_series(minrd, maxrd, interval '1' month) + interval '1 day' as report_date
from m
) m left join
t
on m.report_date = t.report_date;
第一个CTE只是生成样本数据。
【讨论】:
【参考方案2】:这比 Gordon 的查询略有改进,在某些情况下无法获取一个月的最后日期。
基本上,您会在此生成的表格上为每个 ID(使用 generate_series
)和 left join
生成 min
和 max
日期之间的所有月末日期,以显示价格为 0 的缺失日期。
with minmax as (
select id, min(report_date) as mindt, max(report_date) as maxdt
from t
group by id
)
select m.id, m.report_date, coalesce(t.price, 0) as price
from (select *,
generate_series(date_trunc('MONTH',mindt+interval '1' day),
date_trunc('MONTH',maxdt+interval '1' day),
interval '1' month) - interval '1 day' as report_date
from minmax
) m
left join t on m.report_date = t.report_date
Sample Demo
【讨论】:
以上是关于在 Postgresql 的时间序列数据中添加缺少的每月日期的主要内容,如果未能解决你的问题,请参考以下文章
如果在包含架构上授予 USAGE 权限,Postgresql 将忽略缺少 EXECUTE 权限
安装 postgresql92-server postgresql92-contrib 时缺少 libssl.so.10