I need a SQL query to get the value between two known strings (the returned value should start and end with these two strings).
An example.
"All I knew was that the dog had been very bad and required harsh punishment immediately regardless of what anyone else thought."
In this case the known strings are "the dog" and "immediately". So my query should return "the dog had been very bad and required harsh punishment immediately"
I've come up with this so far but to no avail:
SELECT SUBSTRING(@Text, CHARINDEX('the dog', @Text), CHARINDEX('immediately', @Text))@Text being the variable containing the main string.
Can someone please help me with where I'm going wrong?
216 Answers
The problem is that the second part of your substring argument is including the first index. You need to subtract the first index from your second index to make this work.
SELECT SUBSTRING(@Text, CHARINDEX('the dog', @Text)
, CHARINDEX('immediately',@text) - CHARINDEX('the dog', @Text) + Len('immediately')) 1 I think what Evan meant was this:
SELECT SUBSTRING(@Text, CHARINDEX(@First, @Text) + LEN(@First), CHARINDEX(@Second, @Text) - CHARINDEX(@First, @Text) - LEN(@First)) 1 An example is this: You have a string and the character $
String :
aaaaa$bbbbb$cccccCode:
SELECT SUBSTRING('aaaaa$bbbbb$ccccc',CHARINDEX('$','aaaaa$bbbbb$ccccc')+1, CHARINDEX('$','aaaaa$bbbbb$ccccc',CHARINDEX('$','aaaaa$bbbbb$ccccc')+1) -CHARINDEX('$','aaaaa$bbbbb$ccccc')-1) as My_StringOutput:
bbbbb 3 You need to adjust for the LENGTH in the SUBSTRING. You were pointing it to the END of the 'ending string'.
Try something like this:
declare @TEXT varchar(200)
declare @ST varchar(200)
declare @EN varchar(200)
set @ST = 'the dog'
set @EN = 'immediately'
set @TEXT = 'All I knew was that the dog had been very bad and required harsh punishment immediately regardless of what anyone else thought.'
SELECT SUBSTRING(@Text, CHARINDEX(@ST, @Text), (CHARINDEX(@EN, @Text)+LEN(@EN))-CHARINDEX(@ST, @Text))Of course, you may need to adjust it a bit.
0I had a similar need to parse out a set of parameters stored within an IIS logs' csUriQuery field, which looked like this: id=3598308&user=AD\user¶meter=1&listing=No needed in this format.
I ended up creating a User-defined function to accomplish a string between, with the following assumptions:
- If the starting occurrence is not found, a
NULLis returned, and - If the ending occurrence is not found, the rest of the string is returned
Here's the code:
CREATE FUNCTION dbo.str_between(@col varchar(max), @start varchar(50), @end varchar(50)) RETURNS varchar(max) WITH EXECUTE AS CALLER
AS
BEGIN RETURN substring(@col, charindex(@start, @col) + len(@start), isnull(nullif(charindex(@end, stuff(@col, 1, charindex(@start, @col)-1, '')),0), len(stuff(@col, 1, charindex(@start, @col)-1, ''))+1) - len(@start)-1);
END;
GOFor the above question, the usage is as follows:
DECLARE @a VARCHAR(MAX) = 'All I knew was that the dog had been very bad and required harsh punishment immediately regardless of what anyone else thought.'
SELECT dbo.str_between(@a, 'the dog', 'immediately')
-- Yields' had been very bad and required harsh punishment ' 3 Try this and replace '[' & ']' with your string
SELECT SUBSTRING(@TEXT,CHARINDEX('[',@TEXT)+1,(CHARINDEX(']',@TEXT)-CHARINDEX('[',@TEXT))-1) I have a feeling you might need SQL Server's PATINDEX() function. Check this out:
So maybe:
SELECT SUBSTRING(@TEXT, PATINDEX('%the dog%', @TEXT), PATINDEX('%immediately%',@TEXT)) SELECT
SUBSTRING( '', charindex('@','',1) + 1, charindex('.','',1) - charindex('@','',1) - 1 ) 0 DECLARE @Text VARCHAR(MAX), @First VARCHAR(MAX), @Second VARCHAR(MAX)
SET @Text = 'All I knew was that the dog had been very bad and required harsh punishment immediately regardless of what anyone else thought.'
SET @First = 'the dog'
SET @Second = 'immediately'
SELECT SUBSTRING(@Text, CHARINDEX(@First, @Text), CHARINDEX(@Second, @Text) - CHARINDEX(@First, @Text) + LEN(@Second)) 0 You're getting the starting position of 'punishment immediately', but passing that in as the length parameter for your substring.
You would need to substract the starting position of 'the dog' from the charindex of 'punishment immediately', and then add the length of the 'punishment immediately' string to your third parameter. This would then give you the correct text.
Here's some rough, hacky code to illustrate the process:
DECLARE @text VARCHAR(MAX)
SET @text = 'All I knew was that the dog had been very bad and required harsh punishment immediately regardless of what anyone else thought.'
DECLARE @start INT
SELECT @start = CHARINDEX('the dog',@text)
DECLARE @endLen INT
SELECT @endLen = LEN('immediately')
DECLARE @end INT
SELECT @end = CHARINDEX('immediately',@text)
SET @end = @end - @start + @endLen
SELECT @end
SELECT SUBSTRING(@text,@start,@end)Result: the dog had been very bad and required harsh punishment immediately
SELECT SUBSTRING('aaaaa$bbbbb$ccccc',instr('aaaaa$bbbbb$ccccc','$',1,1)+1, instr('aaaaa$bbbbb$ccccc','$',1,2)-1) -instr('aaaaa$bbbbb$ccccc','$',1,1)) as My_String 0 Hope this helps : Declared a variable , in case of any changes need to be made thats only once .
declare @line varchar(100)
set @line =''
select SUBSTRING(@line ,(charindex('-',@line)+1), CHARINDEX('@',@line)-charindex('-',@line)-1) 1 I needed to get (099) 0000111-> (099) | 0000111 like two different columns.
SELECT SUBSTRING(Phone, CHARINDEX('(', Phone) + 0, (2 + ((LEN(Phone)) - CHARINDEX(')', REVERSE(Phone))) - CHARINDEX('(', Phone))) AS CodePhone, LTRIM(SUBSTRING(Phone, CHARINDEX(')', Phone) + 1, LEN(Phone))) AS NumberPhone
FROM Suppliers
WHERE Phone LIKE '%(%)%' DECLARE @text VARCHAR(MAX)
SET @text = 'All I knew was that the dog had been very bad and required harsh punishment immediately regardless of what anyone else thought.'
DECLARE @pretext AS nvarchar(100) = 'the dog'
DECLARE @posttext AS nvarchar(100) = 'immediately'
SELECT CASE WHEN CHARINDEX(@posttext, @Text) - (CHARINDEX(@pretext, @Text) + len(@pretext)) < 0 THEN '' ELSE SUBSTRING(@Text, CHARINDEX(@pretext, @Text) + LEN(@pretext), CHARINDEX(@posttext, @Text) - (CHARINDEX(@pretext, @Text) + LEN(@pretext))) END AS betweentext 1 select substring(@string,charindex('@first',@string)+1,charindex('@second',@string)-(charindex('@first',@string)+1)) 1 Let us consider we have a string DUMMY_DATA_CODE_FILE and we want to find out the substring between 2nd and 3rd underscore(_). Then we use query something like this.
select SUBSTRING('DUMMY_DATA_CODE_FILE',charindex('_', 'DUMMY_DATA_CODE_FILE', (charindex('_','DUMMY_DATA_CODE_FILE', 1))+1)+1, (charindex('_', 'DUMMY_DATA_CODE_FILE', (charindex('_','DUMMY_DATA_CODE_FILE', (charindex('_','DUMMY_DATA_CODE_FILE', 1))+1))+1)- charindex('_', 'DUMMY_DATA_CODE_FILE', (charindex('_','DUMMY_DATA_CODE_FILE', 1))+1)-1)) as Code