我有一个月和一天;我正在尝试计算下一个日期,即在给定日期之后这个月和日会存在。
例如,如果我有一个如下表,其中reference_date的格式为'MMDD'
。请不要因此而责备我;这是在英国提交申请的官方格式。
create table tmp_ben_dates ( filing_date date, reference_date varchar2(4));
insert all
into tmp_ben_dates values ( to_date('31/12/2011','dd/mm/yyyy'), '1231')
into tmp_ben_dates values ( to_date('31/12/2011','dd/mm/yyyy'), '1130')
into tmp_ben_dates values ( to_date('31/12/2011','dd/mm/yyyy'), '0101')
into tmp_ben_dates values ( to_date('31/07/2011','dd/mm/yyyy'), '0601')
into tmp_ben_dates values ( to_date('31/07/2011','dd/mm/yyyy'), '0801')
select * from dual;
我想在每个reference_date
之后返回每个filing_date
发生的第一个日期。例如,在第一个例子中,这将是2012年12月31日,最后一个将是01/08/2011。
到目前为止,我最好的尝试如下
with new_date as (
select reference_date
, filing_date
, add_months( trunc(filing_date,'y')
, to_number(substr(reference_date,1,2)) - 1)
+ to_number(substr(reference_date,3)) - 1 as the_date
from tmp_ben_dates
)
select filing_date
, reference_date
, case when filing_date < the_date then next_date
else add_months(the_date,12) end
from new_date
返回正确的结果:
FILING_DATE REFE NEXT_DATE
------------------- ---- -------------------
31/12/2011 00:00:00 1231 31/12/2012 00:00:00
31/12/2011 00:00:00 1130 30/11/2012 00:00:00
31/12/2011 00:00:00 0101 01/01/2012 00:00:00
31/07/2011 00:00:00 0601 01/06/2012 00:00:00
31/07/2011 00:00:00 0801 01/08/2011 00:00:00
然而,这也是完全荒谬的;难以阅读和理解。
也可以使用interval
,但我真的不知道如何让它更难以确定发生了什么。
with new_date as (
select reference_date
, filing_date
, trunc(filing_date,'y')
+ to_yminterval( 'P'
|| to_char(to_number(substr(reference_date,1,2)) - 1)
|| 'M')
+ to_dsinterval( 'P'
|| to_char(to_number(substr(reference_date,3)) - 1)
|| 'D') as the_date
from tmp_ben_dates
)
select filing_date
, reference_date
, case when filing_date < the_date then the_date
else add_months(the_date,12) end as next_date
from new_date
我在这里遗失的东西真的很明显吗?在SQL中有一种简单的方法吗?
答案 0 :(得分:2)
您可能会发现这更简单。它只是将日期放在YYYYMMDD格式中,并将其用作to_date()的第二个参数:
with new_date as (
select reference_date, filing_date,
to_date(to_char(filing_date, 'yyyy')||reference_date), 'yyyymmdd'
) - 1 as the_date
from tmp_ben_dates
)
select filing_date, reference_date,
(case when filing_date < the_date then next_date
else add_months(the_date,12)
end)
from new_date