Sql server SQL Server-检查是否存在具有特定值的记录

Sql server SQL Server-检查是否存在具有特定值的记录,sql-server,Sql Server,我在SQL Server中遇到了一个非常简单的问题: 用户可以有12个项目,这些项目在表中以ID表示,插槽为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

我在SQL Server中遇到了一个非常简单的问题:

用户可以有12个项目,这些项目在表中以ID表示,插槽为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)
有了这些数据,它确实会正确返回2

ID  Slot Name
10    0  abc
11    1  abc

脚本应该返回1,因为这是第一个低于11的未使用数字槽。

问题的主要困难在于它需要发明数据。MSSQL如何知道您的插槽编号为0-11?为什么不是-3-19?显然,答案是因为你这么说了,但是你需要告诉MSSQL

  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)
在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

@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
或:


你能发布一些种子数据和你期望下一个值是什么,这样我们就可以清楚你需要什么了。保罗:这很奇怪。如果你有3和4,你也会期望0。但我得到的是5。我编辑的答案对你有用吗?谢谢,不过也不行。它仍然返回现有插槽之后的第一个空插槽。我将数据添加到原始posttrue。根据您编辑的问题和示例,上述方法不起作用。
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
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
      )