Это было бы просто RegEx, если ... SQL Server поддерживает RegExes. Я рекомендую использовать другой инструмент для замены значений - любой основной язык программирования с доступом к базе данных и поддержкой RegEx. Если это частая операция, используйте CLR Functions . И потом, помните:
повторять человеческое, повторять божественное
Вот почему:
WITH Splitter AS
(
SELECT id, 1 num, SUBSTRING(name, 1, charindex(' ',name)-1) Word, SUBSTRING(name, charindex(' ',name), LEN(name)) Rest FROM stringrep
UNION ALL
SELECT
id,
num+1 num,
CASE WHEN charindex(' ',Rest)=1 THEN ' '
WHEN charindex(' ',Rest)=0 THEN Rest
ELSE SUBSTRING(Rest, 1, charindex(' ',Rest)-1) END Word,
CASE WHEN charindex(' ',Rest)=1 THEN SUBSTRING(Rest, 2, LEN(Rest))
WHEN charindex(' ',Rest)=0 THEN ''
ELSE SUBSTRING(Rest, charindex(' ',Rest), LEN(Rest)) END Rest
FROM Splitter
WHERE LEN(rest)>0
), Replacer AS
(
SELECT S1.id, S1.num, CASE WHEN LastNotSpace='happy' AND Word='happy' AND (LastLastNotSpace IS NULL OR LastLastNotSpace!='happy') THEN 'new' ELSE Word END NewWord
FROM Splitter S1
LEFT JOIN (SELECT id,num,LAG(Word) OVER (PARTITION BY id ORDER BY num) LastNotSpace, LAG(Word,2) OVER (PARTITION BY id ORDER BY num) LastLastNotSpace FROM Splitter WHERE Word!=' ') T ON S1.id=T.id AND S1.num=T.num
), Joiner AS
(
SELECT id, num, CAST(NewWord AS nvarchar(MAX)) Joined FROM Replacer WHERE num=1
UNION ALL
SELECT S.id, S.num, J.Joined+S.NewWord Joined FROM Joiner J
JOIN Replacer S ON J.id=S.id AND J.num+1=S.num
), Filter AS
(
SELECT id, Joined FROM (
SELECT id, num, Joined, ROW_NUMBER() OVER (PARTITION BY id ORDER BY num DESC) Lev FROM Joiner
) T WHERE Lev=1
)
SELECT * FROM Filter