如何将列添加到generate_series查询

时间:2014-09-19 19:50:23

标签: sql postgresql time-series greenplum generate-series

在查看日期范围时,是否仍有generate_series返回开始日期和结束日期?

select 
    '2014-06-05 00:00:00'::timestamp + ('1 month'::INTERVAL * s.a) AS date 
from 
    generate_series(1, cast(extract(month from age('2014-09-05'::date, '2014-06-05'::date)) AS integer), 1) as s(a);

提供此输出

date
2014-07-05 00:00:00
2014-08-05 00:00:00
2014-09-05 00:00:00

这很好,但我想要

start_date     end_date       date
2014-06-05    2014-09-05    2014-07-05 00:00:00
2014-06-05    2014-09-05    2014-08-05 00:00:00
2014-06-05    2014-09-05    2014-09-05 00:00:00

原因是我从另一个表中提取多个开始/结束对,但无法找到将它们连接在一起的方法。我也使用PostgeSQL版本8.2.15(因此更复杂的generate_series函数)。

要将此扩展为我的主要问题,我有一个包含这些开始和结束时间对的表。

    start_date         end_date
2014-08-25 00:00:00 2014-09-25 00:00:00
2014-05-16 00:00:00 2014-08-16 00:00:00
2014-09-09 00:00:00 2014-12-09 00:00:00
2014-06-05 00:00:00 2014-07-05 00:00:00
2014-05-19 00:00:00 2014-08-19 00:00:00
2014-05-15 00:00:00 2014-07-15 00:00:00
2014-09-04 00:00:00 2014-11-04 00:00:00

如何遍历此表并将其与扩展日期范围相结合?

1 个答案:

答案 0 :(得分:1)

考虑升级到current version。 Postgres 8.2已经很久没死了。

对于Postgres 8.2(或更高版本,但在现代Postgres中有更优雅的解决方案)。

假设所有关于日期,而不是时间戳。

提供start_dateend_date 一次

SELECT start_date, end_date
     , (start_date + interval '1 month'
                   * generate_series(1, months))::date AS the_date
FROM  (  
   SELECT extract(month from age(end_date, start_date))::int AS months
        , start_date, end_date
   FROM (SELECT '2014-06-05'::date AS start_date
              , '2014-09-05'::date AS end_date
        ) data
   ) sub;

使用不应用作标识符的列名the_date而不是date

从表t中绘制值:

SELECT start_date, end_date
     ,(start_date + interval '1 month'
                  * generate_series(1, months))::date AS the_date
FROM  (SELECT *, extract(month FROM age(end_date, start_date))::int AS months
       FROM   t) sub;

没有子查询

SELECT t_id, start_date, end_date
     ,(start_date + interval '1 month'
                  * generate_series(1, extract(month from age(end_date
                                                            , start_date))::int)
                  )::date AS the_date
FROM   t;

SQL Fiddle for Postgres 8.3.