2010-04-03 41 views
4

我正在致力於預留座位的系統。用戶輸入他們希望保留的座位數量,並且數據庫將返回一組先前未保留的與所保留的座位數相匹配的建議座位。SQL - 查找給定大小的連續條目

舉例來說,如果我有表:

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

,他們希望保留2個席位的用戶輸入,我希望查詢返回的是座椅(3,4),(4,5 )和(8,9)不保留並且與給定數量的輸入座位相匹配。席位被組織成部分和行。連續席位必須位於同一行。

我該如何解決這個查詢的結構問題,以便找到與給定輸入匹配的所有可用連續席位?

+1

SQL什麼味道? MySQL的? SQL Server 2000? 2005年? 2008年? – Thomas 2010-04-03 04:11:16

+0

對不起,是MySQL的。 – 2010-04-03 05:01:24

回答

2

使用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 

注意它返回ID的3,4,和8,因爲有開始在每個這些位置的兩個自由席。

這也假設座位ID總是連續的。如果沒有,你可以進入ROW_NUMBER()

+0

感謝您的幫助。不得不爲MySQL修改它,但除此之外,它完美地工作。 – 2010-04-03 05:00:55

+0

很酷。樂於幫助! – 2010-04-03 05:03:53

1

此解決方案僅適用於SQL Server 2005+或某些其他支持CTE的產品。另外,我假定「Reserved」中的內容與您的示例中的字符串相同,而不是一點。最後,我認爲SeatId是完全順序:

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 
0
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