2

I am working in mssql database. I have the following scenario,

I have values in row as

2-5,10-12,67-89....

I need a sql query to fetch only those rows which has atleast one range that contains the user input.

For ex if the user input is 4, then there should be atleast one range that contains 4 like (1-5).

Is it possible to achieve the same with single query.

4
  • 1
    Does your field in the table contains 2-5 or it has two columns from and to where the values are 2 and 5 respectively Commented Dec 4, 2012 at 6:59
  • Are these ranges in the same rows or each range is in a separate row? Commented Dec 4, 2012 at 7:08
  • give your field type or sample input/output Commented Dec 4, 2012 at 7:14
  • The ranges are in the same row Commented Dec 4, 2012 at 7:54

1 Answer 1

3

Try this:

DECLARE @numberToFind INT = 4;
;WITH CTE
AS
(
    SELECT 
      arange,
      SUBSTRING(arange, 1, CHARINDEX('-', arange,1) - 1) "From",
      SUBSTRING(arange, 
                CHARINDEX('-', arange,1) + 1, 
                          LEN(arange) - CHARINDEX('-', arange,1) + 1) "To"
    FROM @ranges
) 
SELECT arange
FROM CTE
WHERE @numberToFind BETWEEN "From" AND "To";

SQL Fiddle Demo

If these ranges are stored as a single varchar string, then you have to parse these comma separated ranges first like so:

DECLARE @ranges VARCHAR(100) = ('2-5,10-12,67-89');
declare @numberToFind INT = 4;

DECLARE @Xml xml =  CONVERT(xml,
                            '<root><s>' + 
                            REPLACE(@ranges, ',', '</s><s>') + 
                            '</s></root>');

;WITH ParsedRanges
AS
(
    SELECT arange = T.c.value('.','varchar(20)')
    FROM @Xml.nodes('/root/s') T(c)
), CTE
AS
(
    SELECT 
      arange,
      SUBSTRING(arange, 1, CHARINDEX('-', arange,1) - 1) "From",
      SUBSTRING(arange, 
                CHARINDEX('-', arange,1) + 1, 
                LEN(arange) - CHARINDEX('-', arange,1) + 1) "To"
    FROM ParsedRanges
) 
SELECT arange
FROM CTE
WHERE @numberToFind BETWEEN "From" AND "To";

SQL Fiddle Demo

Sign up to request clarification or add additional context in comments.

6 Comments

Will it be possible to include this logic in a function. When I try to include it in a function it shows "Select statements included within a function cannot return data to a client." error
@AnandB - Yes, it should be normally included in a function, you might have an error in your select query, please edit your question and show that function you tried. Also, if possible try to setup a demo for the function you tried in this site
I am able to include the logic in function but I get "Invalid length paramter passed to substring "error when the ranges value has values without "-". For eg, @ranges VARCHAR(100) = ('2-5,15,10-12,67-89');
I fixed the issue by checking for index of '-'
There is a performance issue when the ranges value is large(near to varchar (6000)) or when the number of records is large in database. Will it be possible to check if numberToFind exists between "From" and "To" seperately for each "-" character instance and exit loop if match is found.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.