views:

46

answers:

4

Following is the table and script of this table.

DECLARE @temp TABLE (PPId INT, SVPId INT, Minimum INT, Maximum INT)

INSERT INTO @temp VALUES(1,1,8,20)
INSERT INTO @temp VALUES(2,1,21,100)

alt text

Minimum & Maximum are passed in as parameter. I want to find all rows that fall in the given range.

E.g.;

  • If @minimum = 9 and @maximum = 15 then it falls in the range of first row.
  • If @minimum = 21 and @maximum = 22 then it falls in the range of 2nd row.
  • If @minimum = 7 and @maximum = 25 then it falls in the range of both rows so both rows should be returned.

Thanks.

+3  A: 

When comparing ranges like this, it's easier to look for the case where ranges don't overlap. There are many different ways that two ranges can overlap, but there is only two ways that the don't overlap:

select *
from @temp
where not (@maximum < Minimum or @minimum > Maximum)
Guffa
Thanks Guffa, Great help.
Muhammad Kashif Nadeem
+2  A: 
SELECT  *
FROM    @temp
WHERE   minimum <= @max
        AND maximum >= @min
Quassnoi
It can sometimes take someone a few tries to recognise that this covers all the combinations (partial overlaps, and one range entirely within/without the other). Was about to post the same.
Damien_The_Unbeliever
I think this one is my favourite response.
Joel Goodwin
Note: That treats the end values as exclusive rather than inclusive, i.e. the ranges 8-20 and 20-22 does not overlap.
Guffa
If @min and @max both are same like @min = 21 and @max = 21 then it will not work.
Muhammad Kashif Nadeem
Quassnoi has fixed using non-strict inequality operators <= and >= which then makes it the true contrapositive of Guffa's query.
Joel Goodwin
Thanks Quassnoi, Great help.
Muhammad Kashif Nadeem
Yes, now it's the same expression, as `not(a or b)` is the same as `(not a) and (not b)`.
Guffa
A: 

My suggested answer is so simple I suspect either I'm missing something or the question is not complete?

SELECT *
FROM @temp
WHERE Minimum < @Minimum
    AND Maximum > @Maximum
Daniel Renshaw
This finds rows that entirely overlap the @min and @max range, rather than partial overlaps (where @min or @max falls within the range defined by a particular row)
Damien_The_Unbeliever
A: 

I can see what you're trying to do. You want to know how many min/max ranges overlap with the provide min/max range. Try this:

SELECT * FROM @temp T
WHERE  @minimum  BETWEEN T.minimum AND T.maximum
OR     @maximum  BETWEEN T.minimum AND T.maximum
OR     T.minimum BETWEEN @minimum  AND @maximum
OR     T.maximum BETWEEN @minimum  AND @maximum

This should return all rows that intersect with the interval [@minimum, @maximum].

Joel Goodwin
This is longer than the others as I hand-picked this out of my own C# code which was seeking the actual intersection (and thus had to break it down into each scenario separately) and not just boolean success of intersection.The other options by Guffa and Quassnoi are much better for just when testing for whether the intersection is empty or not.
Joel Goodwin