views:

185

answers:

4

I have a situation similar to the following question:

Insert Data Into SQL Table

Where my scenario differs is that I have a non-auto-incrementing primary key field that can have a range between 1000 and 1999. We only have about a hundred values in it thus far, but the maximum value has already been taken (1999), and there are gaps in the numbering sequence. Thus, I need to find a value that is between 1000-1999 and not taken. For instance, if my current values are, for example, 1000, 1001, 1003, and 1999, I would want the query to return 1002.

+4  A: 

try this:

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

OUTPUT:

-----------
3

(1 row(s) affected)

EDIT
this will give the same result:

;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
KM
Worked like a charm. Thanks!
Geo Ego
All of this seems *massively* over complicated given the question. All you need to do is find the first number available, right? **CROSS JOIN?**
astander
+1  A: 

The simplest way I can think of is to create a table with values 1000-1999 then do the following:

Select MIN(Values.Key)
From Main
Left Join Values on Values.Key = Main.Key
Where Main.Key is Null

But someone else can probably come up with a more elegant solution

Dan
A: 

EDIT: Looks like KM Beat me to it... use his solution.

I have a different answer that may be better than my other one.

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

This will find the lowest number that doesn't have another number 1 above it.

Dan
A: 

Not quite sure if I misunderstood the question but have a look at something like

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

Results in

PK
-----------
2

From where you can pick (2 + 1) X-).

astander