今回もNOT EXISTSの利用です。
前回の問題にプラスアルファし、列が一緒でないと連続でも意味ない仕様にします。
例えば下記のようなテーブルがあるとします。
seat | row_id | status
——+——–+——–
1 | A | 占
2 | A | 占
3 | A | 空
4 | A | 空
5 | A | 空
6 | B | 占
7 | B | 占
8 | B | 空
9 | B | 空
10 | B | 空
11 | C | 空
12 | C | 空
13 | C | 空
14 | C | 占
15 | C | 空
seatとstatusは一緒なのですが、row_idが一緒でないと意味がないとします。
例えば10~11などは続けて座れません。
これは始点と終点の列名がおなじであることをいれてあげればOKです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
SELECT s1.seat as start_seat , '~' as connect_string , s2.seat as end_seat FROM seats2 s1 , seats2 s2 WHERE s2.seat = s1.seat + 2 AND s1.row_id = s2.row_id AND NOT EXISTS ( SELECT s3.* FROM seats2 s3 WHERE s3.status = '占' AND s3.seat BETWEEN s1.seat AND s2.seat ); |
一応模範解答のものをのせておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<pre class="lang:mysql decode:true " >SELECT s1.seat as start_seat , '~' as connect_string , s2.seat as end_seat FROM seats2 s1 , seats2 s2 WHERE s2.seat = s1.seat + 2 AND NOT EXISTS ( SELECT s3.* FROM seats2 s3 WHERE s3.seat BETWEEN s1.seat AND s2.seat AND ( s3.row_id <> s1.row_id OR s3.status = '占' ) );</pre> |
これはNOT EXISTSの中に条件を入れています。NOT EXISTSの章は論理構造を扱っているので、筆写の方はその手法を理解してほしかったんだろうと思います。論理関係がちょっとむずいですね。