【问题标题】:How to apply Reverse STUFF in SQL Server如何在 SQL Server 中应用反向 STUFF
【发布时间】:2015-12-14 10:11:18
【问题描述】:

我有一个带空格的字符串值,我想用我的情况来划分它

'Hello John Smith' 在这里我想在下面的 while 循环中

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

你能给我一个解决方案吗?

【问题讨论】:

  • 所以你只想拆分它?
  • 你想拆分但不像 Hello , John , Smith .. 想要 'Hello John Smith', 'Hello John', 'Hello'
  • 循环比基于集合的方法效率低得多

标签: sql-server sql-server-2008 sql-server-2012


【解决方案1】:

这不是超级优化的解决方案,但这只是我的想法。只需反转你的字符串,你就会得到你想要的:

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

【讨论】:

    【解决方案2】:

    试试这个。使用计数进行拆分。不喜欢循环:

    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
    

    【讨论】:

    • 感谢您的回答。它对我有用。实际上我想要循环只是因为我必须对每个单词进行操作。例如,如果我们考虑上面的字符串,那么我必须从表中搜索带有以下单词的记录 'Hello John Smith'、'Hello John'、'Hello'、'John'、'Smith'。
    【解决方案3】:

    通常最好避免循环:

    • 这里我使用递归 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 在大表上效率不高,因为我无法使用索引。

    【讨论】:

    • 感谢您的回答。它对我有用。但我想在while循环中使用。对于每个字符串我必须进行操作。
    • 你的字符串是在表中还是在变量中?
    • 它是一个动态变量。
    • 我不明白你想做什么。你的动态变量是什么?
    • 字符串是从前端传递的,并且必须从表中搜索字符串中的每个单词的记录,例如,如果我们考虑上面的字符串,那么我必须从表中搜索带有以下单词'Hello John Smith'的记录,“你好约翰”,“你好”,“约翰”,“史密斯”。希望你现在明白了。
    猜你喜欢
    • 2021-09-09
    • 2015-09-21
    • 2017-07-06
    • 1970-01-01
    • 2018-08-22
    • 2023-01-24
    • 1970-01-01
    • 2011-01-07
    相关资源
    最近更新 更多