patternsqlMinor
Efficiently search for a prefix range in SQL Server
Viewed 0 times
efficientlysearchserversqlrangeforprefix
Problem
Let's say I want all records with a prefix between two user-supplied alphanumeric values of the same length. Thus, if the user enters
What I've tried:
-
Obviously, I cannot use
-
Technically,
-
I could use
-
I could "explode" the range and search for every possible prefix, e.g.
Is there some smart solution that I've missed? I'll probably use option 3 to solve the problem (since I know about the length and the range of allowed characters), but I'm curious about the general case.
A010 and A025, I want to return A0101, A0200 and A0259.What I've tried:
-
Obviously, I cannot use
WHERE myText BETWEEN @from and @to, because that won't return A0259.-
Technically,
WHERE LEFT(myText, @len) BETWEEN @from AND @to, would be exactly what I want, but that kills SARGability.-
I could use
WHERE myText BETWEEN @from and @to + 'zzzzzzzzzzz', but that is an ugly hack and potentially error-prone. (Is z really the highest character? Did I use enough "padding" characters?)-
I could "explode" the range and search for every possible prefix, e.g.
WHERE (myText LIKE 'A01%' OR myText LIKE 'A020%' OR myText LIKE 'A021%' ...), but that's a lot of work.Is there some smart solution that I've missed? I'll probably use option 3 to solve the problem (since I know about the length and the range of allowed characters), but I'm curious about the general case.
Solution
If you use the
Below is a query that returns all the rows in your range of
>= and < operators you can return the required range by "increasing the second argument" by 1. Technically, replacing the last character ('5') with the next character ('6') in the character set.Below is a query that returns all the rows in your range of
A010 and A025. To get this I pass 'A026' as the second argument. The expression < 'A026' includes the value 'A0259456546'.DECLARE @Test TABLE
(
Val NVARCHAR(100)
) ;
INSERT @Test
VALUES ('A0004534543'),
('A01034950834'),
('A020043553'),
('A0259456546'),
('A0264565464') ;
SELECT *
FROM @Test
WHERE Val >= 'A010'
AND Val < 'A026' ;Code Snippets
DECLARE @Test TABLE
(
Val NVARCHAR(100)
) ;
INSERT @Test
VALUES ('A0004534543'),
('A01034950834'),
('A020043553'),
('A0259456546'),
('A0264565464') ;
SELECT *
FROM @Test
WHERE Val >= 'A010'
AND Val < 'A026' ;Context
StackExchange Database Administrators Q#132839, answer score: 7
Revisions (0)
No revisions yet.