2015-12-14 2 views
2

У меня есть строковое значение с пространством, и я хочу разделю его мое дело, какКак применить обратный STUFF в SQL Server

«Hello John Smith», и здесь я хочу в то время как цикл, как показано ниже

Hello John Smith 
Hello John 
Hello 

Я использовал STUFF:

declare @SearchName varchar(50) = 'Hello John Smith' 

while len(@SearchName) > 0   
begin 
    select @SearchName 

    set @SearchName = replace(@SearchName,' ',' ')  
    set @SearchName = replace(@SearchName,' ',' ')    
    set @SearchName = stuff(@SearchName, 1, charindex(' ', @SearchName+' '), '') 
END 

Но здесь я получаю выход, как показано ниже:

Hello John Smith 
John Smith 
Smith 

Не могли бы вы дать мне решение для этого?

+0

так что вы просто хотите, чтобы разбить его? –

+0

Я хочу разбить, но не нравится Привет, Джон, Смит .. хочу «Привет, Джон Смит», «Привет, Джон», «Привет» –

+0

Петли гораздо более неэффективны, чем установленные подходы –

ответ

3

Это не супер оптимизированное решение, но это только с головы. Просто измените свою строку, и вы получите то, что хотите:

DECLARE @SearchName VARCHAR(50) = REVERSE('Hello John Smith') 
WHILE LEN(@SearchName) > 0 
    BEGIN 
     SELECT REVERSE(@SearchName) 
     SET @SearchName = REPLACE(@SearchName, ' ', ' ')  
     SET @SearchName = REPLACE(@SearchName, ' ', ' ')  

     SET @SearchName = STUFF(@SearchName, 1, CHARINDEX(' ', @SearchName + ' '), '') 
    END 
1

Обычно лучше избегать петель:

  • Здесь я использую рекурсивных CTE, чтобы получить позицию каждого пространства.
  • Мне нужно только довести левую часть строки до каждой позиции.

Запрос:

declare @SearchName varchar(50) = 'Hello John Smith'; 

with cte as (
    SELECT id = 0, p = CHARINDEX(' ', @SearchName) 
    UNION ALL 
    SELECT id+1, p = CHARINDEX(' ', @SearchName, p+1) FROM cte 
    WHERE p > 0 

) 
SELECT * FROM your table d 
INNER JOIN (
    SELECT [string] = CASE WHEN p=0 THEN @SearchName 
     ELSE LEFT(@SearchName, p-1) END 
    FROM cte 
) c ON d.[yourvalue] LIKE '%'+c.string+'%' 
; 

Выход:

Hello John Smith 
Hello John 
Hello 

LIKE с '%' в начале не будет эффективным на большом столе, потому что я не могу использовать индекс.

+0

Спасибо за ваш ответ. его можно использовать для me.but я хочу использовать во время цикла. для каждой строки я должен выполнить операцию. –

+0

- ваша строка в таблице или в переменных? –

+0

его динамическая переменная. –

3

Попробуйте это. Использование tally для разделения. Не поклонник петель:

DECLARE @SearchName varchar(50) = 'Hello John Smith' 

;WITH 
N(N)AS 
(SELECT 1 FROM(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1))M(N)), 
tally(N)AS(SELECT TOP (LEN(@SearchName) + 1) 
ROW_NUMBER()OVER(ORDER BY N.N)FROM N,N a,N b,N c,N d,N e,N fm) 
SELECT LEFT(@SearchName, N - 1) FROM tally 
WHERE substring(@SearchName +' ', N, 1) = ' ' 
ORDER BY N DESC 

Результат:

Hello John Smith 
Hello John 
Hello 
+0

Спасибо за ваш ответ. его можно использовать для меня. На самом деле я хочу цикл только потому, что я должен делать операцию над каждым словом. например, если мы рассмотрим выше строку, то мне нужно искать записи из таблицы со следующими словами: «Привет, Джон Смит», «Привет Джон», «Привет», «Джон», «Смит». –