我在SQL Server中遇到了一个非常简单的问题:
用户可以有12个项目,表格中包含ID和Slot(插槽为0-11)。拾取物品时,应将其放入最低的空槽中。
我正在使用以下脚本,但它在第一个使用的插槽后返回第一个空插槽:
SELECT coalesce ((SELECT MIN(Slot) + 1 FROM Items N1 WHERE N1.name = 'abc'
AND NOT EXISTS(SELECT * FROM Items N2 WHERE N2.name = 'abc'
AND N2.Slot = N1.Slot + 1) AND Slot<11),0)
我需要脚本来找到尚不存在的最低插槽。希望它有意义:))
示例 - 如果表包含以下记录,则不起作用,返回5(应返回0):
ID Slot Name
10 3 abc
11 4 abc
使用此数据,它确实正确返回2.
ID Slot Name
10 0 abc
11 1 abc
脚本应返回1,因为这是第一个未使用的数字(Slot)低于11。
答案 0 :(得分:1)
SELECT coalesce (
(SELECT MIN(N1.Slot) + 1
FROM Items N1
LEFT OUTER JOIN Items N2 ON N1.Slot+1 = N2.Slot
WHERE N1.name = 'abc'
AND N2.Slot IS NULL
AND N1.Slot < 11)
,0)
答案 1 :(得分:1)
DECLARE @Items TABLE (
ID INT,
Slot INT,
Name VARCHAR(50)
)
INSERT INTO @Items VALUES (10, 0, 'ABC')
INSERT INTO @Items VALUES (11, 2, 'ABC')
INSERT INTO @Items VALUES (12, 3, 'ABC')
INSERT INTO @Items VALUES (13, 0, 'EFG')
INSERT INTO @Items VALUES (14, 1, 'EFG')
INSERT INTO @Items VALUES (15, 2, 'EFG')
INSERT INTO @Items VALUES (16, 3, 'EFG')
INSERT INTO @Items VALUES (17, 4, 'EFG')
SELECT
i.Name,
MIN(i.Slot + 1) AS LowestSlot
FROM
@Items i
LEFT JOIN @Items i2 ON i2.Slot = i.Slot + 1 AND i2.Name = i.Name
WHERE
-- i.Slot + 1 < 11 or, i.Slot < 10
i.Slot < 10 AND
i2.ID IS NULL
GROUP BY
i.Name
答案 2 :(得分:1)
问题的主要困难在于它需要发明数据。 MSSQL如何知道您的插槽编号为0 - 11?为什么不-3 - 19?显然,答案是“因为你这么说”,但你需要告诉MSSQL。
在MSSQL中,您可以创建一个表变量来保存基本的插槽信息,然后将Items表连接起来以确定哪些是空的
DECLARE @tv TABLE (
ID INT
)
INSERT INTO @tv
VALUES
(0),
(1),
(2),
(3),
(4),
(5),
(6),
(7),
(8),
(9),
(10),
(11)
SELECT
MIN(t.ID) + 1 AS EmptySlot
FROM
@tv t
LEFT JOIN Item i
ON t.ID = i.ID
WHERE
ISNULL(i.Slot, 0) = 0
答案 3 :(得分:0)
@ simon查询的变体。它适用于SQL-Server 2008:
SELECT
MIN(t.Slot) AS EmptySlot
FROM
( VALUES
(0), (1), (2), (3),
(4), (5), (6), (7),
(8), (9), (10), (11)
) AS t(Slot)
LEFT JOIN
Items AS i
ON i.Slot = t.Slot
WHERE
i.Slot IS NULL
或:
SELECT
MIN(t.Slot) AS EmptySlot
FROM
( VALUES
(0), (1), (2), (3),
(4), (5), (6), (7),
(8), (9), (10), (11)
) AS t(Slot)
WHERE
NOT EXISTS
( SELECT *
FROM Items AS i
WHERE i.Slot = t.Slot
)