HiveBrain v1.2.0
Get Started
← Back to all entries
patternsqlMinor

Optimize a SQL query

Submitted by: @import:stackexchange-dba··
0
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

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
End


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

Solution

Quite convoluted but should work and return the 2 rows with values below the @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.