使用PostgreSQL在未来增加1个月

时间:2012-08-27 16:02:05

标签: sql postgresql datetime

我有三列看起来像这样:

Column1       Date1         Date2
Test2         2012-06-10    
Test8         2012-05-05    2012-06-10

我将首先根据此数据集描述我想要的输出。它看起来像这样:

Year    Month    Sum
2012    05       1
2012    06       2
2012    07       1

如果Column1包含一个数字(可以通过以下内容找到:WHERE Column1 LIKE'%2%'),则应将此数字添加到Date1中的月份值。这是第一行的情况,即第06行和第07行添加了1。但是,对于第2行的情况,如果Date2中有日期,则只应将1添加到Date1,每个月添加到和包括Date2中的月份。这就是为什么将1添加到05和06.

我猜这个查询会使用INTERVAL函数,但我不确定将来如何将值添加到月份。

更新

@CraigRinger - 我会再尝试解释一下。我想使用Column1中的数字来确定将来运行Date1中的日期的月份。对于第一行,它将从2012-06到2012-07运行(因为在Column1中有2个)。

Date2可视为取消日期。因此对于第二行,Date1将持续8个月,但由于它被取消(按日期2),它仅从05到06运行。

换句话说,查询应该在开始月份(Date1)和每个月(包括结尾)添加1(如果存在,则添加Date2)。

我想在这几个月中每增加一个,这样我就知道所有行的月份总和。我猜这会涉及到Date1添加一个日期间隔(等于Column1中的数字),从这两个数字之间的日期中提取月份并向它们添加一个。不幸的是,我不知道如何最好地实现这一点。

希望我这次更好地解释了它!

2 个答案:

答案 0 :(得分:7)

将一个月添加到postgres中的日期的语法是:

select <date> + cast('1 months' as interval)

你的其余逻辑相当令人费解,但你的问题似乎是关于将日期添加到几个月。

答案 1 :(得分:3)

根据上面的数据样本,以下内容就足够了:

create table ddata(test text, d1 date, d2 date);
insert into ddata values ('Test2','2012-06-10'::date,null),('Test8','2012-05-05','2012-6-10')

从字符串值

获取月数
SELECT substring(test,E'\\d+$') FROM ddata;

获取填充第二个日期的月份差异

SELECT ((extract(year FROM d2) - extract(year FROM d1)) *12) + extract(month FROM d2) - extract(month FROM d1)
  FROM ddata;

使用case语句将它们放在一起以决定使用哪个月计算和generate_series来生成要计算的中间日期列表:

SELECT extract(year FROM ccal.cdate),
       extract(month FROM ccal.cdate),
       count(*) AS test_count
FROM
(SELECT generate_series(mcal.d1, mcal.d1 + CAST((mcal.num_mths || ' months') AS INTERVAL), '1 month') AS cdate
  FROM
(SELECT d1,
       CASE (d2 IS NULL)
            WHEN TRUE THEN
                substring(test,E'\\d+$')::integer - 1
            ELSE 
                ((extract(year FROM d2) - extract(year FROM d1)) *12) + extract(month FROM d2) - extract(month FROM d1)
            END as num_mths
 from ddata) as mcal

 )AS ccal
GROUP BY 1,2
ORDER BY 1,2;