我的情况类似于以下问题:
我的场景不同之处在于我有一个非自动递增的主键字段,其范围可以在1000到1999之间。到目前为止我们只有大约一百个值,但是已经取得了最大值(1999),编号顺序存在差距。因此,我需要找到一个介于1000-1999之间但未采用的值。例如,如果我的当前值是,例如,1000,1001,1003和1999,我希望查询返回1002。
答案 0 :(得分:5)
试试这个:
declare @YourTable table (PK int)
insert @YourTable VALUES (1)
insert @YourTable VALUES (2)
insert @YourTable VALUES (4)
insert @YourTable VALUES (7)
insert @YourTable VALUES (8)
SELECT
MIN(y.PK)+1
FROM @YourTable y
LEFT OUTER JOIN @YourTable y2 ON y.PK+1=y2.PK
WHERE y.PK>=1 AND y.PK<10 AND y2.PK IS NULL
输出:
-----------
3
(1 row(s) affected)
修改强>
这将得到相同的结果:
;with N AS
(SELECT TOP 1000 row_number() over(order by t1.object_id) as Number
FROM sys.objects t1
CROSS JOIN sys.objects t2
)
SELECT
MIN(Number) AS PK
FROM N
LEFT OUTER JOIN @YourTable y on n.Number=y.PK
WHERE y.PK IS Null
答案 1 :(得分:1)
我能想到的最简单的方法是创建一个值为1000-1999的表,然后执行以下操作:
Select MIN(Values.Key)
From Main
Left Join Values on Values.Key = Main.Key
Where Main.Key is Null
但其他人可能会提出更优雅的解决方案
答案 2 :(得分:1)
编辑:看起来像KM打败我...使用他的解决方案。
我有一个不同的答案可能比我的另一个好。
Select Min(Main1.Key)+1
From Main as Main1
Left Join Main as Main2 on Main1.Key+1=Main2.Key
Where Main2.Key is Null
这将找到没有其他数字1的最低数字。
答案 3 :(得分:1)
我不太确定我是否误解了这个问题,但看看像
这样的东西declare @YourTable table (PK int)
insert @YourTable VALUES (1)
insert @YourTable VALUES (2)
insert @YourTable VALUES (4)
insert @YourTable VALUES (7)
insert @YourTable VALUES (8)
SELECT TOP 1
*
FROM @YourTable yt
WHERE NOT EXISTS (
SELECT 1
FROM @YourTable
WHERE yt.PK+1 = PK
)
ORDER BY yt.PK
结果
PK
-----------
2
从哪里可以选择(2 + 1) X - )。
答案 4 :(得分:1)
即使所选范围内没有记录,也会产生正确的答案。这也允许按字段分组以按组获得一组最低值。此示例中的SKU是指序号。
SELECT A.myType,
COALESCE (MIN( A.sku) + 1, 1) AS SKU /* 1 is Min Default + 1 */
FROM ( SELECT distinct myType, sku
FROM dbo.myTable AS p1
where p1.sku > 0 /* zero is Min Value */
and p1.sku < 100 /* 100 is Max Value */
union
select distinct myType, 0 as sku /* Guarantee Min Value */
from dbo.myTable as t1
) AS A
LEFT OUTER JOIN
( SELECT distinct myType, sku
FROM dbo.myTable AS p2
where p2.sku > 0 /* zero is Min Value */
and p2.sku < 100 /* 100 is Max Value */
union
select distinct myType, 0 as sku /* Guarantee Min Value */
from dbo.myTable as t2
) AS B
ON A.myType = B.myType AND
A.sku + 1 = B.sku
where (B.sku IS NULL)
GROUP BY A.myType
distinct
实际上加快了查询速度,即使union
已经执行了distinct
。只要你有myType和SKU的索引,就应该是即时的。
显然,您可以将0替换为最低值,将100替换为允许值最高的值。
答案 5 :(得分:1)
这 How do I find a "gap" in running counter with SQL?
select
MIN(ID)
from (
select
1000 ID
union all
select
[YourIdColumn]+1
from
[YourTable]
where
--Filter the rest of your key--
) foo
left join
[YourTable]
on [YourIdColumn]=ID
and --Filter the rest of your key--
where
[YourIdColumn] is null