Извлеките год из дня / месяца в postgresql и проверьте, является ли дата первой или последней датой года. - PullRequest
0 голосов
/ 26 ноября 2018

Java-приложение читает файл CSV, этот файл имеет 2 столбца:

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

X и Y - ось X и ось Y соответственно, где X предполагается датой.Он пропускает год.

Я должен вставить эти значения в таблицу, для этого я готовлю функцию ():

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 - у приложения (или этого файла) всегда был вчерашний день и завтрашний день, иногда даже послезавтра.

Чего бы я хотел достичь :

Идея состоит в том, чтобы разработать функцию так, чтобы она читала год (возможно, из 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 голосов
/ 29 ноября 2018

Может быть полезно для некоторых людей, ищущих то, что я искал в тот день:

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 за его ответ, который мне очень помог.

0 голосов
/ 26 ноября 2018

Я могу придумать два решения: построить дату из строки 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');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...