简而言之,我希望创建一个查询,以帮助我找到音乐会类型场地的最佳可用座位,就像 Ticketmaster.com 的“查找最佳可用座位”,其中要求找到最靠近舞台的座位数量并且座位必须按顺序排列。
鉴于此示例表:
DECLARE @Seats TABLE
(
SectionId INT NOT NULL,
RowId VARCHAR(2) NOT NULL,
SeatId INT NOT NULL,
Priority INT NOT NULL, /* Used to determine closeness to the stage and/or order to search in */
StatusCd CHAR(1) NOT NULL, /* A for Available, H for Held, P for Purchased, etc. */
Cost MONEY NOT NULL
)
并给出这个脚本来填充表格:
DECLARE @SectionCounter INT
DECLARE @RowCounter INT
DECLARE @SeatCounter INT
SET @SectionCounter = 1
SET @RowCounter = 1
WHILE @SectionCounter <= 10
BEGIN
WHILE @RowCounter <= 26
BEGIN
SET @SeatCounter = 1
WHILE @SeatCounter <= 26
BEGIN
INSERT INTO @Seats
( SectionId ,
RowId ,
SeatId ,
Priority ,
StatusCd ,
Cost
)
VALUES
( @SectionCounter ,
CHAR(64 + @RowCounter) ,
@SeatCounter ,
1 ,
(
/* Randomly setting certain seats as purchased */
SELECT CASE
WHEN @SeatCounter IN
(
1,2,9,10,
(ROUND(((26 - 1 -1) * RAND() + 1), 0)),
(ROUND(((26 - 1 -1) * RAND() + 1), 0)),
(ROUND(((26 - 1 -1) * RAND() + 1), 0)),
(ROUND(((26 - 1 -1) * RAND() + 1), 0)),
(ROUND(((26 - 1 -1) * RAND() + 1), 0)),
(ROUND(((26 - 1 -1) * RAND() + 1), 0)),
(ROUND(((26 - 1 -1) * RAND() + 1), 0))
)
THEN 'P' ELSE 'A' END) ,
(
SELECT CASE
WHEN @SectionCounter IN (1,2)
THEN 75.00 ELSE 25.00 END
)
)
SET @SeatCounter = @SeatCounter + 1
END
SET @RowCounter = @RowCounter + 1
END
SET @RowCounter = 1
SET @SectionCounter = @SectionCounter + 1
END
找到 x 个连续/连续座位的最佳查询是什么?
以下是我当前的解决方案,我的应用程序至少需要 3 个查询。
例如,如果客户要求 8 个下一个最佳可用座位,我将运行以下查询:
/* Get each sections available seat count */
SELECT SectionId,
Priority,
COUNT(SeatId) AS 'Seat Count'
FROM @Seats
WHERE StatusCd = 'A' /* A = Available. */
GROUP BY SectionId, Priority
ORDER BY Priority
这将产生如下结果集:
| SectionId | Priority | SeatCount |
|-----------|----------|-----------|
| 1 | 1 | 544 |
| 2 | 2 | 554 |
| 3 | 3 | 552 |
应用程序会说“是否有 8 个座位可用,优先级为 1?” 使用上面的结果集,答案是肯定的,所以让我们获取相应部分的可用行数,即第 1 部分。这是查询:
SELECT RowId,
COUNT(SeatId) AS 'Seat Count'
FROM @Seats
WHERE SectionId = 1
AND StatusCd = 'A'
GROUP BY RowId
这将产生如下结果集:
| RowId | SeatCount |
|-------|-----------|
| A | 21 |
| B | 18 |
| C | 22 |
应用程序会查看这些结果并从第一排开始询问相同的问题:“A 排有 8 个座位吗?” 有了上面的结果,答案是肯定的,所以那个时候应用程序会用这个查询来查询 A 行的所有座位:
SELECT *
FROM @Seats
WHERE SectionId = 1
AND RowId = 'A'
这将产生如下结果集:
| SectionId | RowId | SeatId | Priority | StatusCd | Cost |
|-----------|-------|--------|----------|----------|-------|
| 1 | A | 1 | 1 | P | 75.00 |
| 1 | A | 2 | 1 | P | 75.00 |
| 1 | A | 3 | 1 | A | 75.00 |
| 1 | A | 4 | 1 | A | 75.00 |
| 1 | A | 5 | 1 | A | 75.00 |
那时,应用程序将遍历结果,尝试连续查找 8 个座位,并且 StatusCd 为“A”以表示可用。
我确信有一种更有效的方法可以查询数据库中的顺序记录,而无需加载整行并在代码中执行。
对于最佳解决方案,我最好的猜测是在表上进行自连接,并对 SeatId 进行某种递增或类似的操作。
非常感谢任何帮助或建议。