我正在研究一个预留座位的系统。用户输入他们希望保留的座位数,数据库将返回一组建议的座位,这些座位之前未预留,与预订的座位数相匹配。
例如,如果我有桌子:
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)不保留并匹配给定的号码输入席位。座位分为部分和行。连续座位必须在同一行。
我如何构建此查询以使其找到与给定输入匹配的所有可用连续席位?
答案 0 :(得分: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()
。
答案 1 :(得分:1)
此解决方案仅适用于SQL Server 2005+或其他支持CTE的产品。另外,我假设“保留”输入的存储方式与示例中的字符串相反,而不是位。最后,我认为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
答案 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