Seats3テーブル Row_ID Seat Status ------ ---- ------ A 1 占 A 2 占 A 3 空 A 4 空 A 5 空 B 6 占 B 7 空 B 8 空 B 9 空 B 10 空 C 11 空 C 12 占 C 13 占 C 14 空 C 15 空 Row_IDごとの、Seatの昇順で、Statusが3つ連続して、空 となるSeatを以下の形式で出力する 出力結果 Row_ID SeatStart SeatEnd ------ --------- ------- A 3 5 B 7 9 B 8 10プログラマのためのSQL第2版の24章[リージョン、ラン、シーケンス]を参考にさせていただきました
create table Seats3 as select 'A' as Row_ID,1 as 座席,'占' as 状態 from dual union select 'A', 2,'占' from dual union select 'A', 3,'空' from dual union select 'A', 4,'空' from dual union select 'A', 5,'空' from dual union select 'B', 6,'占' from dual union select 'B', 7,'空' from dual union select 'B', 8,'空' from dual union select 'B', 9,'空' from dual union select 'B',10,'空' from dual union select 'C',11,'空' from dual union select 'C',12,'占' from dual union select 'C',13,'占' from dual union select 'C',14,'空' from dual union select 'C',15,'空' from dual;
--■■■分析関数を使わない方法■■■
select a.座席 as SeatStart,b.座席 as SeatEnd
from Seats3 a,Seats3 b
where a.Row_ID = b.Row_ID
and a.座席 < b.座席
and exists(select 1 from Seats3 c
where c.Row_ID = a.Row_ID
and c.座席 between a.座席 and b.座席
having 3 = all(count(*),count(nullif(c.状態,'占'))));
--■■■分析関数を使う方法■■■
select SeatStart,SeatEnd
from (select 座席 as SeatStart,
Lead(座席,3-1) over(partition by Row_ID order by 座席) as SeatEnd,
count(nullif(状態,'占'))
over(partition by Row_ID order by 座席
Rows between current row and (3-1) following) as SeatCount
from Seats3)
where SeatCount = 3;
Count関数は、nullをカウントしないことと、 nullif関数を組み合わせてます。