--■■■旅人算の感覚を使う方法■■■
select min(num) as Low,max(num) as High,data
from (select num,data,
Row_Number() over(order by num)
- Row_Number() over(partition by data order by num) as distance
from T)
group by data,distance
order by min(num);
--■■■標準SQLを使う方法1■■■
select min(num) as Low,max(num) as High,data
from (select num,data,
(select count(*)+1 from T b
where b.num > a.num) as Rn1,
(select count(*)+1 from T b
where b.data = a.data
and b.num > a.num) as Rn2
from T a)
group by data,Rn1-Rn2
order by min(num);
--■■■標準SQLを使う方法2■■■
select min(num) as Low,max(num) as High,data
from (select num,data,
(select count(*)
- count(case when b.data = a.data
then 1 end)
from T b
where b.num > a.num) as distance
from T a)
group by data,distance
order by min(num);
--■■■標準SQLを使う方法3■■■
select min(num) as Low,max(num) as High,data
from (select a.num,a.data,
count(*)
- count(case when a.data = b.data
then 1 end) as distance
from T a,T b
where a.num <= b.num
group by a.num,a.data)
group by data,distance
order by min(num);