patternsqlMinor
Optimize a SQL query
Viewed 0 times
sqlqueryoptimize
Problem
I have to select 2 values that were less that the given id and greater than the given id. I have tried this query but is there any better way to do it
Fiddle Sql
I forgot to add something at any point there should be 5 records if at all there are that many records satisfying the condition.
Example
The ID's are 1,2,3,4,5 if I supply 2 then also it should return 5
Fiddle Sql
Begin
declare @rootValue int
declare @repID int
set @repID = 2
set @rootValue = (select Id from tblLookups where Id = @repID)
declare @rootMinusTwo int
declare @rootPlusTwo int
set @rootMinusTwo = (select count(*) from tblLookups where Id @rootValue)
if @rootMinusTwo >= 2 and @rootPlusTwo >= 2
Begin
select *
from tblLookups
where Id between @rootValue - 2 and @rootValue + 2
End
else if @rootMinusTwo = 2
select *
from tblLookups
where Id = @repID
union
select *
from tblLookups
where Id @rootValue
else if @rootMinusTwo >= 2 and @rootPlusTwo @rootValue
union
select top(4 - @rootPlusTwo) *
from tblLookups
where Id @rootValue
EndI forgot to add something at any point there should be 5 records if at all there are that many records satisfying the condition.
Example
The ID's are 1,2,3,4,5 if I supply 2 then also it should return 5
Solution
Quite convoluted but should work and return the 2 rows with values below the
If there are less than 2 values below or above, the query will get more from the other side. In total a maximum of 5 rows will be returned.
Note: the
Tested at SQLfiddle.
@repid, the row with @repid and the 2 rows with values above the @repid (assuming that id is a unique key).If there are less than 2 values below or above, the query will get more from the other side. In total a maximum of 5 rows will be returned.
Note: the
ORDER BY is needed. All three of them (not the 4th, that's only if you need the results in specific order):with a as
( select top (4)
*, rnk = row_number() over (order by id desc)
from tblLookups
where Id = @repID
order by id
),
c as
( select top (5) *
from
( select *
from a
union all
select *
from b
) x
order by rnk
)
select *
from c
order by id ;Tested at SQLfiddle.
Code Snippets
with a as
( select top (4)
*, rnk = row_number() over (order by id desc)
from tblLookups
where Id < @repID
order by id desc
),
b as
( select top (5)
*, rnk = row_number() over (order by id) - 1
from tblLookups
where Id >= @repID
order by id
),
c as
( select top (5) *
from
( select *
from a
union all
select *
from b
) x
order by rnk
)
select *
from c
order by id ;Context
StackExchange Database Administrators Q#106037, answer score: 7
Revisions (0)
No revisions yet.