Reputation: 426
I am trying to do something similiar to this https://stackoverflow.com/a/11058109/1383668. The difference is I have entire words that are capital and dynamic. This is the data
THE box is on the desk by the door WILLIAM ran ten miles in world record time DO you know the way to San Jose APPLES to apples is a baking term that is used often when making a pie
This is how it should look when I run it.
THE box is on the desk by the door
WILLIAM ran ten miles in world record time
DO you know the way to San Jose
APPLES to apples is a baking term that is used often when making a pie
Upvotes: 0
Views: 47
Reputation: 81970
With the aid of a split/parse function
To be clear, I added a little bit of logic to trap single letter capital words such as I. len(RetVal)>1
To Aaron's point, double words may require a lead/lag trap.
Example
Declare @S varchar(max) = 'THE box is on the desk by the door WILLIAM ran ten miles in world record time DO you know the way to San Jose APPLES to apples is a baking term that is used often when making a pie'
;with cte as (
Select *
,grp = sum(case when len(RetVal)>1 and upper(RetVal)=RetVal COLLATE SQL_Latin1_General_CP1_CS_AS then 1 else 0 end) over (order by RetSeq)
From [dbo].[tvf-Str-Parse](@S,' ')
)
Select RN = Grp
,NewValue = Stuff((Select ' ' +RetVal From cte Where Grp=A.Grp Order By RetSeq For XML Path ('')),1,1,'')
From cte A
Group By Grp
Returns
RN NewValue
1 THE box is on the desk by the door
2 WILLIAM ran ten miles in world record time
3 DO you know the way to San Jose
4 APPLES to apples is a baking term that is used often when making a pie
The TVF if Interested
CREATE FUNCTION [dbo].[tvf-Str-Parse] (@String varchar(max),@Delimiter varchar(10))
Returns Table
As
Return (
Select RetSeq = row_number() over (order by 1/0)
,RetVal = ltrim(rtrim(B.i.value('(./text())[1]', 'varchar(max)')))
From ( values (cast('<x>' + replace((Select replace(@String,@Delimiter,'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.'))) as A(x)
Cross Apply x.nodes('x') AS B(i)
);
EDIT - If you don't want to add the Table-Valued Function
;with cte as (
Select *
,grp = sum(case when len(RetVal)>1 and upper(RetVal)=RetVal COLLATE SQL_Latin1_General_CP1_CS_AS then 1 else 0 end) over (order by RetSeq)
From (
Select RetSeq = row_number() over (order by 1/0)
,RetVal = ltrim(rtrim(B.i.value('(./text())[1]', 'varchar(max)')))
From ( values (cast('<x>' + replace((Select replace(@S,' ','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.'))) as A(x)
Cross Apply x.nodes('x') AS B(i)
) A
)
Select RN = Grp
,NewValue = Stuff((Select ' ' +RetVal From cte Where Grp=A.Grp Order By RetSeq For XML Path ('')),1,1,'')
From cte A
Group By Grp
Upvotes: 2