| Author |
Topic |
|
Kbalz
Yak Posting Veteran
94 Posts |
Posted - 2008-10-13 : 16:20:07
|
| I'm trying to find a way to select the lowest 'hole' in a table that holds ID fields for instance, the hole would be between two parameters that I passs to the stored proc@low int = 1@high int = 10Table1ID---------1235679I would expect my select statement or forumula to return 4@low int = 13@high int = 1000Table1ID---------12223252627292I would expect my select statement or forumula to return 13Is there a clean way to do this in SQL? I may solve it in .NET instead, but SQL would me quicker CPU wise.Thanks. |
|
|
hanbingl
Aged Yak Warrior
652 Posts |
Posted - 2008-10-13 : 16:46:37
|
you can do it with a temp table:--SETUP WORK TABLEdrop table #mytabGOcreate table #mytab (ID int)GOinsert into #mytabselect 1union all select 2union all select 3union all select 5union all select 6union all select 7union all select 9UNION ALLselect 12union allselect 22union allselect 32union allselect 52union allselect 62union allselect 72union allselect 92GO-----------You can make this a SP or UDF later----------------declare @sqlstr varchar(8000)declare @low intdeclare @high intset @low = 13set @high = 99set @sqlstr ='declare @checktab table(test1 int identity('+cast(@low as varchar)+',1), id int) insert into @checktab (ID)select [ID] from #mytab where ID between '+cast(@low as varchar)+' and '+cast(@high as varchar)+'order by IDselect min(test1) from @checktab where test1 <> ID'print @sqlstrexecute(@sqlstr) |
 |
|
|
sakets_2000
Master Smack Fu Yak Hacker
1472 Posts |
Posted - 2008-10-13 : 17:48:12
|
| This should work if in case you don't want to use a temptable,declare @low intdeclare @high int--set @low=1--set @high=10set @low=13set @high=1000select top 1 * from (select case when sum(1) is null then @low else '' end as a from test where col1=@lowunion allselect col1+1 as a from test where col1 between @low and @high and col1+1 not in (select col1 from test) )zwhere a<>''order by 1 asc |
 |
|
|
hanbingl
Aged Yak Warrior
652 Posts |
Posted - 2008-10-13 : 18:14:32
|
| very close:won't work if @low = 1@high = 3or @low is out of range |
 |
|
|
hanbingl
Aged Yak Warrior
652 Posts |
Posted - 2008-10-13 : 18:16:20
|
Fixed:declare @low intdeclare @high int--set @low=1--set @high=10set @low=13set @high=1000select top 1 * from(select case when sum(1) is null then @low else '' end as a from test where col1=@lowunion allselect col1+1 as a from test where col1 between @low and @high and col1+1 not in (select col1 from test))zwhere a between @low and @highorder by 1 asc |
 |
|
|
sakets_2000
Master Smack Fu Yak Hacker
1472 Posts |
Posted - 2008-10-13 : 18:39:50
|
quote: Originally posted by hanbingl Fixed:declare @low intdeclare @high int--set @low=1--set @high=10set @low=13set @high=1000select top 1 * from(select case when sum(1) is null then @low else '' end as a from test where col1=@lowunion allselect col1+1 as a from test where col1 between @low and @high and col1+1 not in (select col1 from test))zwhere a between @low and @highorder by 1 asc
ah, nice catch ! |
 |
|
|
Kbalz
Yak Posting Veteran
94 Posts |
Posted - 2008-10-14 : 09:34:25
|
| hanbingl & sakets_2000, thanks.The 'fixed' version works perfectly for me. |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-10-14 : 11:01:18
|
[code]DECLARE @Sample TABLE ( ID INT )INSERT @SampleSELECT 1 UNION ALLSELECT 2 UNION ALLSELECT 3 UNION ALLSELECT 5 UNION ALLSELECT 6 UNION ALLSELECT 7 UNION ALLSELECT 9 UNION ALLSELECT 12 UNION ALLSELECT 22 UNION ALLSELECT 32 UNION ALLSELECT 52 UNION ALLSELECT 62 UNION ALLSELECT 72 UNION ALLSELECT 92DECLARE @Low INT, @High INTSELECT @Low = -10, @High = 22--Peso SELECT MIN(s.ID) AS IDFROM ( SELECT x.ID + 1 AS ID FROM @Sample AS x WHERE x.ID BETWEEN @Low - 1 AND @High - 1 ) AS sWHERE s.ID BETWEEN @Low AND @High AND NOT EXISTS (SELECT * FROM @Sample AS t WHERE t.ID = s.ID)-- hanbingl & sakets2000select top 1 * from(select case when sum(1) is null then @low else '' end as a from @sample where id=@lowunion allselect id+1 as a from @sample where id between @low and @high and id+1 not in (select id from @sample))zwhere a between @low and @highorder by 1 asc[/code]Peso 4Other -10 E 12°55'05.63"N 56°04'39.26" |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
|
|
|