You can use the following query (given X = 3 in this case):
select
a.row,
a.seat,
group_concat(b.status order by b.seat) as status_seq
from seats a
inner join seats b on
a.row = b.row
and a.seat <= b.seat
where a.status = 1
group by a.row, a.seat
having status_seq like '1,1,1%';
The X = 3 is represented by the number of '1' in the last pattern. You can use concat(left(repeat('1,', 3), 3*2-1), '%')
instead of this string pattern to automatically produce it, where the two '3' are X.
The idea is, for every seat where status
is 1
, to get the status of the next seats in the same row, including itself. This sequence is available through the status_seq
value.
For instance, if you set the status of seat A-03 to 0, the status_seq of each available seat will be the following:
+------+------+-------------+
| row | seat | status_seq |
+------+------+-------------+
| A | 01 | 1,1,0,1,1,1 |
| A | 02 | 1,0,1,1,1 |
| A | 04 | 1,1,1 |
| A | 05 | 1,1 |
| A | 06 | 1 |
| B | 01 | 1,1,1 |
| B | 02 | 1,1 |
| B | 03 | 1 |
+------+------+-------------+
Then to get 3 consecutive seats, you just have to filter this result to get every row which sequence starts with '1,1,1', using the having
filter.
This would give you the following result (remember that in this example, seat A-03 is not available):
+------+------+------------+
| row | seat | status_seq |
+------+------+------------+
| A | 04 | 1,1,1 |
| B | 01 | 1,1,1 |
+------+------+------------+
With X = 2:
+------+------+-------------+
| row | seat | status_seq |
+------+------+-------------+
| A | 01 | 1,1,0,1,1,1 |
| A | 04 | 1,1,1 |
| A | 05 | 1,1 |
| B | 01 | 1,1,1 |
| B | 02 | 1,1 |
+------+------+-------------+
Each row in the query result is the first seat of a sequence of X available seats. You can add a final limit 1
if you want to get only the first one.