我有三个列,看起来像这样:
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中的Month值。这是第一行的情况,即为06和07月份添加1。但是,对于第2行的情况,如果在Date2中有日期,则应该只在Date1中添加1,并且应该在Date2中添加每个月(包括该月)。这就是为什么在05和06上加1的原因。
我猜这个查询将使用INTERVAL函数,但是我不确定我应该如何在将来的月份中添加值。
更新:
@CraigRinger -我会再解释一遍。我想使用Column1中的数字来确定Date1中的日期将在未来几个月后运行。对于第一行,它将从2012-06运行到2012-07 (因为在Column1中有一个2)。
可以将Date2视为取消日期。因此,对于第二行,Date1将持续8个月,但由于它被取消(由Date2),它仅从05运行到06。
换句话说,查询应该在开始月份(Date1)和结束之前的每个月(或Date2,如果存在)上加1。
我想将这些月份中的每一个月加1,这样我就可以知道我所有行的月份总和。我猜这将涉及到向Date1添加一个日期间隔(等于Column1中的数字),从这两个数字之间的日期中提取月份,并向它们添加一个1。不幸的是,我不知道如何最好地实现这一点。
希望这次我已经解释得更好了!
发布于 2012-08-28 18:19:48
根据上面的数据样本,以下内容应该足够了:
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-28 00:24:28
在postgres中向日期添加月份的语法为:
select <date> + cast('1 months' as interval)您的其余逻辑相当复杂,但您的问题似乎是关于向日期添加月份。
https://stackoverflow.com/questions/12145429
复制相似问题