从Postgresql中的日/月中提取年份,并检查日期是否为年份的第一和/或最后一年

时间:2018-11-26 15:29:30

标签: postgresql function date

一个Java应用程序读取一个CSV文件,该文件有2列:

X     Y
22/11 5
23/11 8
24/11 6

X和Y分别是X轴和Y轴,其中X应该是日期。它错过了一年。

我必须在表中插入这些值,为此,我正在准备一个function():

BEGIN
 UPDATE my_table set timestamp=to_timestamp(in_x_data), price=in_y_data WHERE timestamp = to_timestamp(in_x_data);
 IF FOUND THEN 
  RETURN;
 END IF;
 BEGIN 
  INSERT INTO my_table ( timestamp, price ) VALUES ( to_timestamp(in_x_data), in_y_data );
 END;
RETURN;
END;

由于X不是时间戳记,所以我必须找到一种将其“转换”为实际日期的方法:

1)我知道Java应用程序每天运行一次;

2)如果上面的值是这些值,则意味着该应用程序在23/11上运行-该应用程序(或此文件)始终具有昨天和明天的某天,有时甚至是后天。 / p>

我想要实现的目标

这个想法是要开发该函数,以便它读取年份(也许来自select date_part('year', now());),并使用该值(2018)来创建实际日期:

22/11/2018
23/11/2018
24/11/2018

请牢记这一年的第一年和最后一年,因此我想应该插入IF-ELSE。

类似的东西:

// today is 30/12/2018
year = select date_part('year', now());

new_x_data = to_timestamp(in_x_data + '/' +year);
// new_x_data == 01/01/2018
IF (new_x_data was long time ago ) { 
  new_x_data = to_timestamp(in_x_data + '/' +year+1);
  // new_x_data == 01/01/2019
}

不好意思,我杀死了几十年的编程。

嗯,这同样适用于年初和年末前后的未来和过去的日子。

我不知道如何做,对PLpgSQL也不太熟悉。

2 个答案:

答案 0 :(得分:1)

我可以想到两种解决方案:从字符串22/11构建日期并从中提取日期和月份,然后将其用作make_date()的输入

select make_date(extract(year from current_date)::int, 
                 extract(month from to_date('22/11', 'dd/mm'))::int, 
                 extract(day from to_date('22/11', 'dd/mm'))::int)

to_date('22/11', 'dd/mm')返回带有年份0001的日期,因此另一种选择是在日期中添加所需的年份。

select (to_date('22/11', 'dd/mm') + interval '1' year * extract(year from current_date)::int)::date

interval添加到date会返回timestamp,这就是为什么需要使用::date将最终结果强制转换为日期的原因


make_date()的替代方法是to_date()

select to_date('22/11'||to_char(current_date,'/yyyy'),'dd/mm/yyyy');

答案 1 :(得分:0)

对于某些搜索我当天搜索内容的人可能有用:

DECLARE
-- accept dd/mm and add current year /yyyy
in_date timestamp;

BEGIN
 SELECT to_date(in_x_data||to_char(current_date,'/yyyy'),'dd/mm/yyyy') INTO in_date;

-- check if month of in_date is January and current date is December, if true, add 1 year to in_date
 IF ( (SELECT date_part('month', in_date) = 1) AND (SELECT date_part('month', now()) = 12) ) THEN
   in_date := in_date + interval '1 year';

-- if in_date is December but current date is January, remove 1 year
 ELSIF   ( (SELECT date_part('month', in_date) = 12) AND (SELECT date_part('month', now()) = 1) ) THEN
   in_date := in_date - interval '1 year';
 END IF;

 UPDATE my_table SET timestamp=in_date, price=in_y_data WHERE timestamp = in_date;
 IF FOUND THEN 
  RETURN;
 END IF;
 BEGIN 
  INSERT INTO my_table ( timestamp, price ) VALUES ( in_date, in_y_data );  
 END;
RETURN;
END;

感谢@a_horse_with_no_name的回答,这对我很有帮助。