4

月と日があります。この月と日が特定の日付の後に存在する次の日付を計算しようとしています。

たとえば、次のようなテーブルがある場合、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でこれを行う簡単な方法はありますか?

4

1 に答える 1

2

これはもっと簡単だと思うかもしれません。単純に日付を YYYYMMDD 形式で入力し、それを to_date() の 2 番目の引数として使用します。

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 
于 2012-08-15T15:48:44.867 に答える