Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Postgresql中的timeseries数据中添加缺少的每月日期_Sql_Postgresql_Window Functions_Sql Date Functions - Fatal编程技术网

在Postgresql中的timeseries数据中添加缺少的每月日期

在Postgresql中的timeseries数据中添加缺少的每月日期,sql,postgresql,window-functions,sql-date-functions,Sql,Postgresql,Window Functions,Sql Date Functions,我在表中有月度时间序列数据,其中日期为每月的最后一天。数据中缺少一些日期。我想插入这些日期,并为其他属性设置零值。 附表如下: 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 pri

我在表中有月度时间序列数据,其中日期为每月的最后一天。数据中缺少一些日期。我想插入这些日期,并为其他属性设置零值。 附表如下:

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是不高效的


谢谢

您可以使用
生成_series()
来生成日期,然后
左连接
来引入值:

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只是生成样本数据。

这比Gordon的查询稍有改进,Gordon的查询在某些情况下无法获取一个月的最后日期

基本上,您可以在此生成的表上为每个id生成
min
max
日期之间的所有月末日期(使用)和
left join
,以显示价格为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