Добавление одного месяца к сохраненной дате (оракул)

У меня есть таблица A, которая содержит атрибут типа Date. Я хочу написать запрос для выбора даты в другой таблице B со значением через месяц после значения в A. Кто-нибудь знает, как это сделать в оракуле?


person SunyGirl    schedule 17.04.2011    source источник
comment
как определить месяц? т. е. если исходная дата 31 января, какова целевая дата? 28 или 29 февраля? В какой-то мартовский день?   -  person Mat    schedule 17.04.2011
comment
Первое число марта. Ровно через месяц после 31 января.   -  person SunyGirl    schedule 17.04.2011
comment
Первая дата марта на самом деле не имеет смысла. Это на два месяца вперед или на 29 или 30 дней вперед.   -  person Mat    schedule 17.04.2011
comment
Хорошо, например, через 2 дня после сохраненной даты, что я могу сделать?   -  person SunyGirl    schedule 17.04.2011
comment
@ user623906: почему 31st Jan + 1 Month == 1st March? Почему не 2nd march или 28/29th Feb?   -  person zerkms    schedule 17.04.2011
comment
@ user623906: вы можете прочитать ответы внизу.   -  person zerkms    schedule 17.04.2011


Ответы (3)


хм... Это был первый поиск в гугле:

http://psoug.org/reference/date_func.html

Кажется, вы ищете функцию «add_months».

person BlueEel    schedule 17.04.2011
comment
Нет, я это видел, это для системной даты, а не для сохраненной даты в таблице. - person SunyGirl; 17.04.2011

Вам нужно использовать функцию ADD_MONTHS в Oracle.

http://www.techonthenet.com/oracle/functions/add_months.php

Дополнительная информация: если вы хотите использовать эту функцию с сегодняшней датой, вы можете использовать ADD_MONTHS(SYSDATE, 1), чтобы получить месяц вперед.

person Adrian Smith    schedule 17.04.2011

Вопрос состоит в том, чтобы выбрать поле даты из таблицы b, где поле даты таблицы b на один месяц опережает поле даты в таблице a.

Необходимо учитывать дополнительное требование, которое в настоящее время не указано в вопросе. Нас интересуют целые месяцы (дни месяца не учитываются) или мы хотим включить дни, которые могут дисквалифицировать даты, отстоящие на один месяц вперед, но только на пару дней (пример: a=2011-04-30 и b=2011-05-01, b опережает на 1 месяц, но только на 1 день).

В первом случае мы должны усечь обе даты до их значений года и месяца:

SELECT TRUNC( TO_DATE('2011-04-22','yyyy-mm-dd'), 'mm') as trunc_date
   FROM dual;

дает:

  trunc_date
  ----------
  2011-04-01

Во втором случае нам не нужно изменять даты.

Для решения исходной задачи можно использовать как минимум два подхода:

Первый вращается вокруг добавления одного месяца к date_field в таблице a и поиска строки в таблице b с соответствующей датой.

SELECT b.date_field
  FROM tab_a as a
      ,tab_b as b
 WHERE ADD_MONTHS( TRUNC( a.date_field, 'mm' ), 1) = TRUNC( b.date_field, 'mm' )
  ;

Обратите внимание на усеченные даты. Если это не учитывать, потребуется идеальное повседневное совпадение между датами.

Второй подход основан на вычислении разницы в месяцах между двумя датами и выборе расчета, который дает разницу в 1 месяц.

SELECT b.date_field
  FROM tab_a as a
      ,tab_b as b
 WHERE months_between( TRUNC( b.date_field, 'mm') , TRUNC(a.date_field, 'mm') ) = 1

Здесь важен порядок полей в month_between. В приведенном примере:

  • для b.date_field за один месяц до a.date_field значение равно 1
  • для b.date_field за месяц до a.date_field значение равно -1 (отрицательное)

Изменение порядка также изменит результаты.

Надеюсь, что это ответ на ваш вопрос.

person mulander    schedule 22.04.2011