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関数を組み合わせてます。