启者
我有一个票务系统。现在,当用户要求2张或3张票时,我必须选择相邻的地方。 每张票都有一个行号和列号。相邻位置的概念与相邻列号位于同一行。 这些票证位于sql server数据库中。有关此算法的任何想法,以搜索可用的相邻席位?
此致
卡米洛
答案 0 :(得分:5)
您可以通过在Column = Column + 1:
上连接表格aginst来获得两个相邻的席位SELECT ...
FROM Seats A
JOIN Seats B ON A.Row = B.Row AND A.Column = B.Column+1
WHERE A.IsReserved = 0
AND B.IsReserved = 0
您可以通过在Column = Column + 1,+ 2,+ 3上重复连接将其扩展到3-4个座位链。如果你想要任何序列长度的更通用的解决方案,你将不得不使用递归CTE并且它变得复杂。对于大多数用例,简单连接都可以正常工作。
例如:
create table Seats (Row int not null
, Col int not null
, IsReserved bit not null
, constraint pkSeatsRowColumn primary key (Row, Col));
go
insert into Seats (Row, Col, IsReserved)
select 1,1,0 union all
select 1,2,0 union all
select 1,3,1 union all
select 1,4,0 union all
select 1,5,0 union all
select 1,6,0 union all
select 2,1,0;
with cteAnchor as (
SELECT Row, Col, 1 as [length]
FROM Seats
WHERE IsReserved = 0)
, cteRecursive as (
SELECT Row, Col, [length]
FROM cteAnchor
UNION ALL
SELECT c.Row, c.Col, c.[length]+1
FROM Seats s
JOIN cteRecursive c
ON s.Row = c.Row and s.Col = c.Col+c.[length]
WHERE s.IsReserved = 0)
select * from cteRecursive
递归查询将返回包含起始座位编号和序列长度的集合中的所有可用座位序列。如果只需要长度为3的序列,则添加必要的WHERE子句,查询将返回座位(1,4),这是我的样本数据中唯一一个旁边有2个可用座位的席位。
答案 1 :(得分:1)
CREATE TABLE #Places(LineNumber INT, ColumnNumber INT, IsOccupied CHAR(1));
GO
DECLARE @NumAdjacent INT;
SET @NumAdjacent = 3;
SELECT * FROM #Places AS p
WHERE @NumAdjacent = (SELECT COUNT(*) FROM #Places AS p1
WHERE p1.LineNumber = p.LineNumber
AND p1.ColumnNumber BETWEEN p.ColumnNumber AND p.ColumnNumber + @NumAdjacent - 1
AND p1.IsOccupied = 'Y');
答案 2 :(得分:0)
WITH places AS
(
SELECT 1 AS row, 1 AS col, 0 AS occupied
UNION ALL
SELECT 1 AS row, 2 AS col, 1 AS occupied
UNION ALL
SELECT 1 AS row, 3 AS col, 0 AS occupied
UNION ALL
SELECT 1 AS row, 4 AS col, 0 AS occupied
UNION ALL
SELECT 1 AS row, 5 AS col, 0 AS occupied
UNION ALL
SELECT 1 AS row, 6 AS col, 1 AS occupied
)
SELECT row, col, len
FROM (
SELECT row, col, COUNT(*) OVER (PARTITION BY row, span) AS len
FROM (
SELECT row, col,
col - ROW_NUMBER() OVER (PARTITION BY row ORDER BY col) AS span
FROM places
WHERE occupied = 0
) q
) q2
WHERE len >= 3
此查询返回3
个或更多地方的所有免费范围。
这里的基本想法是column
是连续的,尽管所有席位和ROW_NUMBER
只在免费席位内是连续的:
column occupied ROW_NUMBER diff
1 0 1 0
2 1 - -
3 0 2 1
4 0 3 1
5 0 4 1
6 1 - -
免费席位的范围在column
和ROW_NUMBER
之间具有相同的差异,并且可以使用此差异对其进行分组。