create table Pensions(
ID varchar2(3),
year number(4),
months number(2) check(months between 0 and 12),
primary key(ID,year));
insert into Pensions values('AAA',2006,12);
insert into Pensions values('AAA',2005,12);
insert into Pensions values('AAA',2004,12);
insert into Pensions values('AAA',2003,12);
insert into Pensions values('AAA',2002,12);
insert into Pensions values('AAA',2001,12);
insert into Pensions values('BBB',2007,12);
insert into Pensions values('BBB',2006,12);
insert into Pensions values('BBB',2005,12);
insert into Pensions values('BBB',2004,12);
insert into Pensions values('BBB',2000,12);
insert into Pensions values('CCC',2007,12);
insert into Pensions values('CCC',2006,12);
insert into Pensions values('CCC',2004,12);
insert into Pensions values('CCC',2003,12);
insert into Pensions values('CCC',2002,12);
insert into Pensions values('CCC',2001,12);
insert into Pensions values('CCC',2000,12);
insert into Pensions values('CCC',1999,12);
insert into Pensions values('DDD',2007,12);
insert into Pensions values('DDD',2006,12);
insert into Pensions values('DDD',2005,12);
insert into Pensions values('DDD',2004,12);
insert into Pensions values('DDD',2003,10);
insert into Pensions values('DDD',2002,10);
insert into Pensions values('EEE',2007,12);
insert into Pensions values('EEE',2006, 0);
insert into Pensions values('EEE',2005, 0);
insert into Pensions values('EEE',2004,12);
insert into Pensions values('EEE',2003,12);
insert into Pensions values('EEE',2002,12);
insert into Pensions values('EEE',2001,12);
insert into Pensions values('EEE',2000,12);
insert into Pensions values('FFF',2009, 5);
insert into Pensions values('FFF',2007, 5);
insert into Pensions values('FFF',2006, 1);
insert into Pensions values('FFF',2005, 1);
insert into Pensions values('FFF',2004,10);
insert into Pensions values('FFF',2003,12);
insert into Pensions values('FFF',2002,12);
insert into Pensions values('FFF',2001,12);
insert into Pensions values('FFF',2000,12);
insert into Pensions values('FFF',1995,12);
insert into Pensions values('FFF',1994,12);
insert into Pensions values('FFF',1993,12);
insert into Pensions values('FFF',1992,12);
insert into Pensions values('FFF',1991,12);
commit;
--■■■分析関数を使う方法1(10g以降)■■■
select ID,year,months
from (select ID,year,months,StartYear,sumMonth,
max(StartYear) over(partition by ID) as maxStartYear
from (select ID,year,months,StartYear,
sum(months) over(partition by ID,StartYear order by year desc)-months as sumMonth,
sum(months) over(partition by ID,StartYear) as TotalsumMonth
from (select ID,year,months,
Last_Value(LagYear ignore nulls)
over(partition by ID order by year desc) as StartYear
from (select ID,year,months,
case Lag(year) over(partition by ID order by year desc)
when year+1 then null else year end as LagYear
from Pensions
where months > 0)))
where sumMonth < 60
and TotalsumMonth >= 60)
where StartYear = maxStartYear
order by ID,year desc;
--■■■分析関数を使う方法2(旅人算の感覚を使用)■■■
select ID,year,months
from (select ID,year,months,dis,max(dis) over(partition by ID) as maxDis
from (select ID,year,months,dis,
sum(months) over(partition by ID,dis) as sumMonths,
sum(months) over(partition by ID,dis order by year desc)-months as RunSum
from (select ID,year,months,
Year+Row_Number() over(partition by ID
order by year desc) as dis
from Pensions
where months >= 1))
where sumMonths >= 60
and RunSum <60)
where dis = maxDis
order by ID,year desc;
--■■■分析関数を使う方法3■■■
select ID,year,months
from (select ID,year,months,
sum(months) over(partition by ID order by year desc)-months as SumMonths
from Pensions a
where 0 < a.months
and exists(select 1 from Pensions b,Pensions c
where a.ID = ALL(b.ID,c.ID)
and 0 < ALL(b.months,c.months)
and a.year between b.year and c.year
and (select sum(d.months)
from Pensions d
where d.ID = a.ID
and 0 < d.months
and d.year between b.year and c.year
having max(d.year) - min(d.year) = count(*) -1) >= 60))
where SumMonths < 60
order by ID,year desc;