Pattern Matching with SQL Like for a range of characters - sql

Is there a way to use Pattern Matching with SQL LIKE, to match a variable number of characters with an upper limit?
For example, I have one column which can have "correct values" of 2-10 numbers, anything more than 10 and less than 2 is incorrect.

If you really want to use like you can do:
where col like '__' or col_like '___' or . . .
or:
where col like '__%' and -- at least two characters
col not like '_________%' -- not 9 characters
The more typical method would be:
where len(col) between 2 and 10
If you want to ensure they are numbers:
where len(col) between 2 and 10 and
col not like '%[^0-9]%'

You could make a function to do this the long way of inspecting each character like below:
DECLARE #TempField varchar(max)= '1v3Abc567'
DECLARE #FieldLength int = LEN(#TempField)
DECLARE #CountNumeric int = 0
WHILE #FieldLength > 0
BEGIN
SELECT #CountNumeric = #CountNumeric + ISNUMERIC( SUBSTRING (#TempField,#FieldLength,1))
SET #FieldLength = #FieldLength - 1
END
SELECT #CountNumeric NumericCount

You can use Regex.
SELECT * FROM mytable WHERE mycol LIKE '%[0-9]{2,10}%';
should do it (that's off the top of my head, so double-check!

Related

searching a specific position in a field

I have a ID field that is 11 chars long 123456789abc
How can I check the length
how can I check position 3 to ensure it's numeric
Select * from table
where ID = position 2 must be 'A-Z'
You can use like with patterns. Something like this:
Select *
from table
where id like '___[0-9]%' and len(id) = #length

Where x character equal value

How can I select records where in the column Value the 5th character is letter A?
For example the following records:
ID Value
-------------------------
1 1234A5636A6363
2 1234A4343B6363
3 1234B5353A6363
if I run
select * from table
where Value like '%A%'
this will return all records
but all I want is the first 2 where the 5th character is A, regardless if there are more A characters in the text or not
select *
from your_table
where substring(Value, 5, 1) = 'A'
The LIKE operator, in addition to %, which matches any number of any character, can use _, which matches any one single character. You may try:
SELECT *
FROM yourTable
WHERE Value LIKE '____A%'; -- 4 underscores here
use like below by using _(underscore)
LIKE '____A%'
SQL Server
select *
from YourTableName
where CHARINDEX('A', ColumnName) = 5
Note:- This finds where string 'A' starts at position 5
AND specify Your ColumnName

Joining on numeric part of string

It's been a while...I'd like to get your advice on the most efficient way to join on only the number part of a field that may be prefixed and/or suffixed with up to 2 letters. Here's a simplified snippet of what I'm trying to do:
SELECT a, b, c
FROM table 1 t1
LEFT JOIN table 2 t2 ON t1.PolicyCode = t2.sPolicyID,
Where t2.sPolicyID could begin and/or end with up to 2 letters. Some examples: TG73100, S7286674, 2344506R, etc. We only want to join to just its numeric part in between the letters, i.e. 73100, 7286674 or 2344506 from the examples.
Could someone please advise on a simple way of doing this?
Here is one way:
LEFT JOIN table 2 t2 ON t1.PolicyCode =
LEFT(SUBSTRING(t2.sPolicyID, PATINDEX('%[0-9]%', t2.sPolicyID), 50),
PATINDEX('%[^0-9]%',
SUBSTRING(t2.sPolicyID, PATINDEX('%[0-9]%', t2.sPolicyID), 50)
+ 'a') -1)
To break this down, there are 4 main parts.
1: Find the position of the first number with PATINDEX:
DECLARE #spolicyID VARCHAR(20) = 'xx123123xx'
SELECT PATINDEX('%[0-9]%', #spolicyID)
--Returns 3
2: Use SUBSTRING() to cut off everything before the first letter:
DECLARE #spolicyID VARCHAR(20) = 'xx123123xx'
SELECT SUBSTRING(#spolicyID, PATINDEX('%[0-9]%', #spolicyID), 50)
--Returns 123123xx
If we hardcoded the 3 that we know is returned from the first part, it would look like this:
DECLARE #spolicyID VARCHAR(20) = 'xx123123xx'
SELECT SUBSTRING(#spolicyID, 3), 50)
--50 is the number of characters to extract, set to something
--higher than the max string length to be safe
Of course, we don't want to hardcode it since it can change, but that makes seeing the different functions a bit easier.
3: Find the position of the next letter using PATINDEX again:
DECLARE #spolicyID VARCHAR(20) = 'xx123123xx'
SELECT PATINDEX('%[^0-9]%', SUBSTRING(#spolicyID, PATINDEX('%[0-9]%', #spolicyID), 50) + 'a')
--Returns 7 since it is looking at 123123xx
--The first x is in the 7th position
Note that we added an a onto the string. This is because if we had a string with no letters at the end, it would throw an error as the length 0 would be returned to SUBSTRING. You could add any letter or letters to the end and it would work, we are just making sure there is at least one. Try removing the + 'a' and using a string like xx123123 to see the error.
If we hardcoded the 123123xx from step 2 it would look like this (again just for easy example):
DECLARE #spolicyID VARCHAR(20) = 'xx123123xx'
SELECT PATINDEX('%[^0-9]%', '123123xx' + 'a')
4: Use LEFT() to return everything before the trailing letters, leaving us with only the numbers in between:
DECLARE #spolicyID VARCHAR(20) = 'xx123123xx'
LEFT(SUBSTRING(#spolicyID, PATINDEX('%[0-9]%', #spolicyID), 50),PATINDEX('%[^0-9]%', SUBSTRING(#spolicyID, PATINDEX('%[0-9]%', #spolicyID), 50) + 'a') -1)
--Need to add `-1` because step 3 PATINDEX returns 7
--as the position of first trailing letter, and
--we want the 6 characters before that
And again hardcoded from step 2 and 3 for easy viewing:
DECLARE #spolicyID VARCHAR(20) = 'xx123123xx'
LEFT('123123xx', 7-1)

Separate numeric inside string variable using patindex

I have here a short problem.
i have a value like this
1/11
11/1
11/11
111/1
111/11
i'm trying to separate those value and put them into numeric variable.
let say for example i have numericvar1 and numericvar2
so in the 1st string numericvar1 will contain 1 and numericvar2 will contain 11
and so on.
i've tried it like this
SET #numericvar1= LEFT(#StrNumHolder, PATINDEX('%[0-9][^0-9]%', #StrNumHolder ))
SET #numericvar2= REPLACE(RIGHT(#StrNumHolder, PATINDEX('%[0-9][^0-9]%', #StrNumHolder )),'/','')
in this code if the first number before / is in 2 digit i got the correct output. But if the first number is in 1 digit and the next number is in 2 digit like 1/11 i got the wrong output. something like this var1 = 1 and var2 = 1
did something wrong in my code? or it is not possible? please help me.
You can use CHARINDEX to get the position of '/' then use SUBSTRING to separate the numbers. Here how you can query it:
DECLARE #nIndex INT
SELECT #nIndex = CHARINDEX('/',#StrNumHolder)
SET #numericvar1 = SELECT SUBSTRING(#StrNumHolder,1,#nIndex-1)
SET #numericvar2 = SELECT SUBSTRING(#StrNumHolder,#nIndex+1,LEN(#StrNumHolder))
Can you try something like this?
DECLARE #STRNUMHOLDER VARCHAR(20)
SET #STRNUMHOLDER='111/1'
DECLARE #pos INT
SET #pos = CHARINDEX('/', #STRNUMHOLDER)
SELECT #STRNUMHOLDER AS ORIG, LEFT(#STRNUMHOLDER, #pos-1) AS NUM1, SUBSTRING(#STRNUMHOLDER, #pos+1,99) AS NUM2

SQL Strings - Filter by Hypen(x number)

I am trying to formulate a query that will allow me to find all records from a single column with 3 hyphens. An example of a record would be like XXXX-RP-XXXAS1-P.
I need to be able to sort through 1000s of records with either 2 or 3 hyphens.
You can REPLACE the hyphens in the string with an empty string and compute the difference of the length of original string and the replaced string to check for the number of hyphens.
select *
from yourtable
where len(column_name)-len(replace(column_name,'-',''))=3
and substring(column_name,9,1) not like '%[0-9]%'
If your records have 2 or 3 hyphens, then just do:
where col like '%-%-%-%'
This will get 3 or more hyphens. For exactly 3:
where col like '%-%-%-%' and col not like '%-%-%-%-%'
try this,
declare #t table(col1 varchar(50))
insert into #t values ('A-B'),('A-B-C-D-E'),('A-B-C-D')
select * from
(SELECT *
,(len(col1) - len(replace(col1, '-', ''))
/ len('-')) col2
FROM #T)t4
where col2=3