Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何从SQL Server获取“下一个可用号码”?(不是标识列)_Sql Server_Sql Server 2008 - Fatal编程技术网

Sql server 如何从SQL Server获取“下一个可用号码”?(不是标识列)

Sql server 如何从SQL Server获取“下一个可用号码”?(不是标识列),sql-server,sql-server-2008,Sql Server,Sql Server 2008,技术:SQL Server 2008 因此,我尝试了一些我在So上找到的选项,但没有什么能真正为我提供一个明确的答案 我有一个包含两列的表,事务ID和GroupID,其中两列都没有唯一的值。例如: TransID | GroupID ----------------- 23 | 4001 99 | 4001 63 | 4001 123 | 4001 77 | 2113 2645 | 2113 123 | 2113 99

技术:SQL Server 2008

因此,我尝试了一些我在So上找到的选项,但没有什么能真正为我提供一个明确的答案

我有一个包含两列的表,事务ID和GroupID,其中两列都没有唯一的值。例如:

TransID | GroupID
-----------------
23      | 4001
99      | 4001
63      | 4001
123     | 4001   
77      | 2113
2645    | 2113
123     | 2113
99      | 2113   
;WITH CTE_Numbers AS (
    SELECT n = 2001
    UNION ALL
    SELECT n + 1 FROM CTE_Numbers WHERE n < 4000 
)
SELECT top 1 n 
FROM CTE_Numbers num
WHERE NOT EXISTS (SELECT 1 FROM MyTable tab WHERE num.n = tab.groupid)
ORDER BY n
最初,groupID只是由用户随机选择的,但现在我们正在将其自动化。问题是,我们保留现有的数据库,而不对现有数据进行任何更改—工作量太大,收益太少


有没有办法在GroupTransactions表上查询GroupID以获得GroupID>2000的下一个可用值?

我想从这个问题来看,您是在寻找下一个可用值,尽管这可能与max+1不同,对吧?-在这种情况下:

select max(groupid) + 1 from GroupTransactions
从整数列表开始,查找groupid列中不存在的整数,例如:

TransID | GroupID
-----------------
23      | 4001
99      | 4001
63      | 4001
123     | 4001   
77      | 2113
2645    | 2113
123     | 2113
99      | 2113   
;WITH CTE_Numbers AS (
    SELECT n = 2001
    UNION ALL
    SELECT n + 1 FROM CTE_Numbers WHERE n < 4000 
)
SELECT top 1 n 
FROM CTE_Numbers num
WHERE NOT EXISTS (SELECT 1 FROM MyTable tab WHERE num.n = tab.groupid)
ORDER BY n

注意:您需要调整CTE中的2001/4000值,以允许您想要的范围。我假设您的表名为MyTable

以下将找到2000年以上的下一个差距:

SELECT MIN(t.GroupID)+1 AS NextID
FROM GroupTransactions t (updlock)
WHERE NOT EXISTS
(SELECT NULL FROM GroupTransactions n WHERE n.GroupID=t.GroupID+1 AND n.GroupID>2000)
AND t.GroupID>2000

做任何事都有很多方法。我这样做解决了这个问题:

declare @i int = null 

declare @t table (i int)
insert into @t values (1)
insert into @t values (2)
--insert into @t values (3)
--insert into @t values (4)
insert into @t values (5)
--insert into @t values (6)

--get the first missing number
select   @i = min(RowNumber)
from (
select  ROW_NUMBER() OVER(ORDER BY i) AS RowNumber, i
    from (
        --select distinct in case a number is in there multiple times
        select distinct i
        from @t
        --start after 0 in case there are negative or 0 number
        where i > 0
    ) as a
) as b 
where RowNumber <> i

--if there are no missing numbers or no records, get the max record
if @i is null
    begin
    select @i = isnull(max(i),0) + 1 from @t
    end

select @i

你需要确保groupID>2000显然,考虑到他的数据,它无论如何都会>2000,但我不确定他为什么会说……根据他给我们的信息,>2000的请求似乎是多余的。在升级之前,用户会随机选择它们。由于用户对编号的选择不当,Maxgroupid返回了数十亿的值。这就是为什么下一个大于2000的可用值更有意义。所以你想填补空白?我认为这在你的问题中是不清楚的,你可能想要编辑来澄清这一点。在并发下它必须是正确的吗?如果两个请求请求下一个GroupID,那么如果两个请求都获得相同的值是否可以,或者返回的值是否也应该是“保留”的,这样其他请求就不能获得相同的值?只有2个用户使用此应用程序,所以我不担心并发性。不过,这似乎是正确的解决方案,我检查了从CTE_Numbers num中重新写入SELECT top 1 n作为从CTE_Numbers num中选择n,因为我没有得到预期的答案,它只给出了接下来的100个值。从你的例子来看,2001-2101。编辑:好的,开始工作了。我唯一关心的是,如果把2001-2101年的所有值都取下来怎么办?它是否在2101之后获得接下来的100个值?您正在达到CTE数字列表上的MAXRECURSION默认限制。您可以通过MAXRECUSION查询提示来控制这一点。有关更多信息,请参阅此链接的相关部分。我建议使用0选项删除限制,然后通过将其设置为MyTable+1中的最大groupid来控制终点4000,这样该范围内将始终具有可用ID。问题得到了解决。我以前从未使用过这种查询,但现在我知道了,我有一种感觉,我会更经常地使用它。谢谢你的帮助@克里斯蒂安:如果你习惯了老式的SQL 2000查询方式,那么有几件事可以让你的生活变得更轻松:这里使用的CTE表、交叉应用、透视/取消分割、OVER/partitionby等等。