Reputation: 249
I have a comma separated string in a table that looks like this:
FirstTitle:name1, SecondTitle:100000, ThirdTitle:600, FourthTitle:100000, RemoveTitle:30, SixthTitle:1234
The 'Title' bit refers to a description of that value, the value itself is held after the ':', in other words the string is made of Title:Value pairs.
I want to remove part of the string - specifically the value with the label 'RemoveTitle'. i.e. I want this:
FirstTitle:name1, SecondTitle:100000, ThirdTitle:600, FourthTitle:100000, RemoveTitle:30, SixthTitle:1234
to become:
FirstTitle:name1, SecondTitle:100000, ThirdTitle:600, FourthTitle:100000, SixthTitle:1234
Importantly, I can't rely on the title:value pairs being in the same order in the string, or on the length of the 'values' being the same.
I can try to use STUFF along the lines of:
DECLARE @StartSubString varchar(100)
SET @StartSubString = 'RemoveTitle:'
STUFF(TableName.columnName,
CHARINDEX(@StartSubString, TableName.columnName ,1),
???,
'')
But In order to work out the length of the substring to Stuff, I need to know the position of the comma following the @StartSubString, which I'm not sure how to get. It may also be the last pair in the string, in which case there won't be a comma following, but I can deal with that issue.
Any help would be very helpfully received!
Upvotes: 0
Views: 480
Reputation: 1269873
Even the brute force method is tricky, because you have to consider a lot of different possibilities -- the string being at the beginning, end, or not present at all. This should work under all circumstances:
with tablename as (
select 'FirstTitle:name1, SecondTitle:100000, ThirdTitle:600, FourthTitle:100000, RemoveTitle:3012345, SixthTitle:1234 ' as col union all
select 'FirstTitle:name1, SecondTitle:100000, ThirdTitle:600, FourthTitle:100000, RemoveTitle:3012345' as col union all
select 'RemoveTitle:3012345' as col union all
select 'FirstTitle:name1, SecondTitle:100000, ThirdTitle:600, FourthTitle:100000' as col
)
select t.col,
coalesce(Stuff(t.col, v.loc, charindex(', ', t.col + ', ', v.loc) - v.loc+2, ''), t.col) as new_col
from tablename t cross apply
(values (PatIndex('%' + @StartSubString +'%', t.col))
) v(loc);
Here is a db<>fiddle.
EDIT:
You can fix the trailing comma using trim()
:
trim(', ' from coalesce(Stuff(t.col, v.loc, charindex(', ', t.col + ', ', v.loc) - v.loc+2, ''), t.col)) as new_col
Upvotes: 1
Reputation: 32609
As ugly as it is, the following is one way to remove your data element using standard string functions. this assumes each element is separated by ', '
, you can adjust as necesary:
declare @remove varchar(50)='RemoveTitle';
with sampledata as (
select 'FirstTitle:name1, SecondTitle:100000, ThirdTitle:600, FourthTitle:100000, RemoveTitle:30, SixthTitle:1234' v
)
select v Original, Stuff(v,s.p, IsNull(NullIf(CharIndex(', ',v,s.p),0),Len(v))-s.p+2,'') Replaced, s.p, CharIndex(', ',v,s.p)
from sampledata sd
cross apply (values(PatIndex(Concat('%',@remove,'%'),v)))s(p)
Upvotes: 1