Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using PATINDEX to find varying length patterns in T-SQL

I'm looking to pull floats out of some varchars, using PATINDEX() to spot them. I know in each varchar string, I'm only interested in the first float that exists, but they might have different lengths.

e.g.

'some text 456.09 other text'
'even more text 98273.453 la la la'

I would normally match these with a regex

  "[0-9]+[.][0-9]+"

However, I can't find an equivalent for the + operator, which PATINDEX accepts. So they would need to be matched (respectively) with:

'[0-9][0-9][0-9].[0-9][0-9]' and '[0-9][0-9][0-9][0-9][0-9].[0-9][0-9][0-9]' 

Is there any way to match both of these example varchars with one single valid PATINDEX pattern?

like image 536
Rich Avatar asked Mar 19 '12 15:03

Rich


People also ask

What does Patindex do in SQL Server?

SQL Server PATINDEX() Function The PATINDEX() function returns the position of a pattern in a string. If the pattern is not found, this function returns 0. Note: The search is case-insensitive and the first position in string is 1.

What is the difference between Charindex and Patindex?

The charindex and patindex functions return the starting position of a pattern you specify. Both take two arguments, but they work slightly differently, since patindex can use wildcard characters, but charindex cannot.

How do I select a substring in SQL after a specific character?

To find the index of the specific character, you can use the CHARINDEX(character, column) function where character is the specific character at which you'd like to start the substring (here, @ ). The argument column is the column from which you'd like to retrieve the substring; it can also be a literal string.


2 Answers

I blogged about this a while ago. Extracting numbers with SQL server

Declare @Temp Table(Data VarChar(100))

Insert Into @Temp Values('some text 456.09 other text')
Insert Into @Temp Values('even more text 98273.453 la la la')
Insert Into @Temp Values('There are no numbers in this one')

Select Left(
             SubString(Data, PatIndex('%[0-9.-]%', Data), 8000),
             PatIndex('%[^0-9.-]%', SubString(Data, PatIndex('%[0-9.-]%', Data), 8000) + 'X')-1)
From   @Temp
like image 155
George Mastros Avatar answered Sep 23 '22 21:09

George Mastros


Wildcards.

SELECT PATINDEX('%[0-9]%[0-9].[0-9]%[0-9]%','some text 456.09 other text')
SELECT PATINDEX('%[0-9]%[0-9].[0-9]%[0-9]%','even more text 98273.453 la la la')
like image 39
Ben Avatar answered Sep 22 '22 21:09

Ben