添加间隔月或日

时间:2015-08-13 13:57:35

标签: sql oracle

我需要能够根据单个静态值和第二个解码值添加两个日期。

我会使用add_months,但它在2周内没有发挥出色。

to_date(procedure_date, 'DD-MON-YYYY') + DECODE(visit_name,'0WK',interval '0' day,'2WK',interval '14' day,'1MO',interval '1' month, '1YR', interval '1' year) as due_date

上述代码的问题在于它不允许我使用多种间隔类型。如果我坚持几天它可以工作,但是一旦我在一个月或一年中添加它就会中断。考虑到可变长度的月份,如果我试着说一个月的30天,那么最终的计算日期在一段时间内是错误的。

ORA-00932: inconsistent datatypes: expected NUMBER got INTERVAL YEAR TO MONTH
00932. 00000 -  "inconsistent datatypes: expected %s got %s"

有办法解决这个问题吗?

1 个答案:

答案 0 :(得分:2)

无论如何,数月和数年的间隔时间都很棘手;如果您的手续日期是2015-08-31,并且您添加了一个月,那么您将获得无效日期(因为9月没有31天);同样,如果您有2016-02-29并且添加了一年,那么您也会遇到同样的问题。

从为两周时间添加天数而不是使用间隔切换可能更简单;使用add_months几个月和几年,在一个简单的case表达式而不是解码中(虽然这也会起作用):

case visit_name
  when '0WK' then to_date(procedure_date, 'DD-MON-YYYY')
  when '2WK' then to_date(procedure_date, 'DD-MON-YYYY') + 14
  when '1MO' then add_months(to_date(procedure_date, 'DD-MON-YYYY'), 1)
  when '1YR' then add_months(to_date(procedure_date, 'DD-MON-YYYY'), 12)
end as due_date

重复to_date()部分 - 但是您应该将日期存储为正确的数据类型而不是字符串,所以这只是您支付的价格的一部分......

使用一些虚拟数据:

with t (procedure_date, visit_name) as (
  select '03-Apr-2015', '2WK' from dual
  union all select '10-Jul-2015', '0WK' from dual
  union all select '15-Aug-2015', '1MO' from dual
  union all select '27-Jan-2015', '1YR' from dual
)
select procedure_date, visit_name,
  case visit_name
    when '0WK' then to_date(procedure_date, 'DD-MON-YYYY')
    when '2WK' then to_date(procedure_date, 'DD-MON-YYYY') + 14
    when '1MO' then add_months(to_date(procedure_date, 'DD-MON-YYYY'), 1)
    when '1YR' then add_months(to_date(procedure_date, 'DD-MON-YYYY'), 12)
    end as due_date
from t;

PROCEDURE_D VIS DUE_DATE 
----------- --- ----------
03-Apr-2015 2WK 2015-04-17
10-Jul-2015 0WK 2015-07-10
15-Aug-2015 1MO 2015-09-15
27-Jan-2015 1YR 2016-01-27