create table dupSortKey(sortKey,Val1,Val2) as
select 1,'AA','XX' from dual union all
select 2,'AA','XX' from dual union all
select 3,'BB','YY' from dual union all
select 4,'BB','YY' from dual union all
select 5,'AA','XX' from dual union all
select 5,'BB','XX' from dual union all
select 6,'AA','YY' from dual union all
select 7,'AA','YY' from dual union all
select 7,'BB','YY' from dual union all
select 8,'AA','YY' from dual;
--■■■旅人算の感覚を使う方法1■■■
select Val1,Val2,min(sortKey) as sta,max(sortKey) as end
from (select sortKey,Val1,Val2,
dense_rank() over(order by sortKey)
-Row_Number() over(partition by Val1,Val2 order by sortKey) as distance
from dupSortKey)
group by Val1,Val2,distance
order by Val1,min(sortKey);
--■■■旅人算の感覚を使う方法2■■■
select Val1,Val2,min(sortKey) as sta,max(sortKey) as end
from (select sortKey,Val1,Val2,
sortKey
-Row_Number() over(partition by Val1,Val2 order by sortKey) as distance
from dupSortKey)
group by Val1,Val2,distance
order by Val1,min(sortKey);
--■■■旅人算の感覚を使わない方法■■■
select Val1,Val2,min(sortKey) as sta,max(sortKey) as end
from (select sortKey,Val1,Val2,
sum(willSum) over(partition by Val1 order by sortKey) as GID
from (select sortKey,Val1,Val2,
case when Val2 = max(Val2) over(partition by Val1
order by sortKey range between 1 preceding
and 1 preceding)
then 0 else 1 end as willSum
from dupSortKey))
group by Val1,Val2,GID
order by Val1,min(sortKey);
--■■■model句を使う方法(10g以降)■■■
select Val1,Val2,min(sortKey) as sta,max(sortKey) as end
from (select sortKey,Val1,Val2,GID
from dupSortKey
model
partition by(Val1)
dimension by(Row_Number() over(partition by Val1 order by sortKey) as rn)
measures(sortKey,Val2,1 as GID)
rules(
GID[any] order by sortKey = case when cv(rn) = 1 then 1
when sortKey[cv()] = sortKey[cv()-1]+1
and Val2[cv()] = Val2[cv()-1] then GID[cv()-1]
else GID[cv()-1]+1 end))
group by Val1,Val2,GID
order by Val1,min(sortKey);