开发者

SQL - Finding continuous entries of a given size

I am working on a system for reserving seats. A user inputs how many seats they wish to reserve and the database will return a set of suggested seats that are not previously reserved that matches the number of seats being reserved.

For instance if I had the table:

SeatID | Reserved
-----------------
1      | false
2      | true
3      | false
4      | false
5      | false
6      | true
7      | true
8      | false
9      | false
10     | true

And the user inputs that they wish to reserve 2 seats, I would expect the query to return that seats (3, 4), (4, 5), and (8, 9) are not reserved and match the given number of input seats. Seats are organized into sections and rows. Conti开发者_如何学运维nuous seats must be in the same row.

How would I go about structuring this query to work in such a way that it finds all available continuous seats that match the given input?


Using SQL Server 2005/2008:

WITH FreeSeatGroups AS
(
    SELECT S1.SeatID AS StartID,
           (SELECT MIN(S2.SeatID)
            FROM Seats S2 
            WHERE S2.SeatID > S1.SeatID
            AND S2.Reserved = 1) - S1.SeatID AS FreeSeatCount
    FROM Seats AS S1
    WHERE S1.Reserved = 0
)
SELECT StartID, FreeSeatCount
FROM FreeSeatGroups
WHERE FreeSeatCount >= 2

Note that this returns IDs 3, 4, and 8, since there are two free seats starting at each of those positions.

This also assumes that Seat IDs are always sequential. If not, you can get into ROW_NUMBER().


This solution will only work in SQL Server 2005+ or some other product that supports CTEs. In addition, I assumed that "Reserved" in was stored just as in your example as a string as opposed to a bit. Lastly, I assumed that SeatId was perfectly sequential:

   With
    StartSeats As
    (
    Select SeatId + 1 As SeatId
    From Seats As S
    Where Reserved = 'true'
        And Not Exists(
                        Select 1
                        From Seats As S2
                        Where S2.SeatId = S.SeatId + 1
                            And S2.Reserved = 'true'
                        )
        And SeatId < ( Select Max(S1.SeatId) From Seats As S1 ) 
    Union All
    Select SeatId
    From Seats
    Where SeatId = 1 
        And Reserved = 'false'
    Union All
    Select SeatId
    From Seats
    Where SeatId = ( Select Max(S1.SeatId) From Seats As S1 )   
        And Reserved = 'false'
    )
    , SeatRanges As
    (
    Select S1.SeatId As FirstOpenSeat, Min(S2.SeatId) As LastReservedSeat
    From StartSeats As S1
        Left Join Seats As S2
            On S2.SeatId > S1.SeatId
                And S2.Reserved = 'true'
    Group By S1.SeatId          
    )
Select *
From SeatRanges
Where LastReservedSeat - FirstOpenSeat = 2


WITH FreeSeatGroups AS
(
   select s1.ss StartID,(select  min (s2.ss) 
   from test123 s2
   WHERE S2.ss >= S1.ss
   and S2.rr = 1) -s1.ss FreeSeatCount  from test123 s1
)
SELECT StartID, FreeSeatCount
FROM FreeSeatGroups
WHERE FreeSeatCount >= 1
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜