Поле месяца - ГГГГММ в форме ЧИСЛА. Хочу получить за предыдущий месяц. Я уже вычисляю предыдущий месяц по декабрь, если текущий месяц - январь Например: 201301 преобразуется в 201212. (Я использую MOD, чтобы проверить последнее, если последние две цифры оцениваются в 1, если да, он уменьшает год и добавляет 12 в качестве месяца )

Я пытаюсь получить предыдущий месяц, если текущий месяц отличается от января. Для этого я попробовал-

  1) select  CONCAT( SUBSTR(201405,1,4),  MOD(201405,100) - 1 )  from dual;
  2) select  CONCAT( SUBSTR(201405,1,4),  SUBSTR(201405,5,6) - 1 )  from dual;

В обоих случаях он возвращает 20144, то есть отбрасывает 0 из текущего месяца. Таким образом, для значения 201405 он должен вернуть 201404.

0
user2441441 25 Фев 2015 в 23:59

2 ответа

Лучший ответ

Попробуй это:

SELECT TO_NUMBER(TO_CHAR(ADD_MONTHS(TO_DATE(DAT,'YYYYMM'),-1),'YYYYMM')) PREV_MONTH 
FROM 
(SELECT 201405 DAT FROM DUAL);

Выход:

PREV_MONTH
----------
    201404
1 row selected.
2
Aramillo 25 Фев 2015 в 21:04

Вы можете использовать INTERVAL (конечно, все это не будет ANSI-совместимым, поэтому было бы глупо вводить интервалы ANSI, но все же):

SELECT TO_NUMBER(TO_CHAR(TO_DATE(TO_CHAR(201405), 'YYYYMM') - INTERVAL '1' MONTH, 'YYYYMM'))
  FROM dual;

Фактически вы можете опустить внутренний вызов TO_CHAR() и просто позволить Oracle выполнить неявное преобразование (хотя я не уверен, что одобряю это):

SELECT TO_NUMBER(TO_CHAR(TO_DATE(201405, 'YYYYMM') - INTERVAL '1' MONTH, 'YYYYMM'))
  FROM dual;

Или вы можете попробовать это:

WITH d1 AS (
    SELECT TO_DATE(TO_CHAR(201405), 'YYYYMM') - INTERVAL '1' MONTH AS new_date
      FROM dual
)
SELECT EXTRACT(YEAR FROM new_date) * 100 + EXTRACT(MONTH FROM new_date)
  FROM d1;
1
David Faber 25 Фев 2015 в 22:35