月と日があります。この月と日が特定の日付の後に存在する次の日付を計算しようとしています。
たとえば、次のようなテーブルがある場合、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
。たとえば、最初の例では 31/12/2012 になり、最後の例では 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でこれを行う簡単な方法はありますか?