3

我有三列看起来像这样:

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 中有日期,它应该只在 Date1 上加 1,并且每个月都加到和包括 Date2 中的月份。这就是为什么将 1 添加到 05 和 06 的原因。

我猜这个查询会使用 INTERVAL 函数,但我不确定我应该如何在未来的几个月中添加值。

更新:

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

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

换句话说,查询应该将 1 添加到开始月份 (Date1) 和每个月,直到并包括结束(或 Date2,如果存在)。

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

希望这次我解释得更好!

4

2 回答 2

7

在 postgres 中将月份添加到日期的语法是:

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

您的其余逻辑相当复杂,但您的问题似乎是关于将月份添加到日期。

于 2012-08-27T16:24:27.807 回答
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;
于 2012-08-28T10:19:47.503 回答