【问题标题】:SQL method to replace repeating blanks with single blanks用单个空格替换重复空格的 SQL 方法
【发布时间】:2010-02-02 09:08:21
【问题描述】:

有没有更优雅的方法来做到这一点。我想用单个空格替换重复的空格......

   declare @i int

    set @i=0
    while @i <= 20
    begin
        update myTable
        set myTextColumn = replace(myTextColumn, '  ', ' ')
        set @i=@i+1
    end

(它的 sql server 2000 - 但我更喜欢通用 SQL)

【问题讨论】:

    标签: sql


    【解决方案1】:

    这行得通:

    UPDATE myTable
    SET myTextColumn =
        REPLACE(
            REPLACE(
                REPLACE(myTextColumn
                    ,'  ',' '+CHAR(1)) -- CHAR(1) is unlikely to appear
            ,CHAR(1)+' ','')
        ,CHAR(1),'')
    WHERE myTextColumn LIKE '%  %'
    

    完全基于集合;没有循环。

    所以我们用一个不寻常的字符和一个空格替换任意两个空格。如果我们称异常字符 X,5 个空格变为:'X X',6 个空格变为'X X X'。然后我们用空字符串替换'X'。所以5个空格变成'',6个空格变成'X'。然后,如果有偶数个空格,我们删除所有剩余的“X”,留下一个空格。

    【讨论】:

    • 从技术上讲,是的。但从技术上讲,几乎任何 SQL 都会涉及循环。我应该说它使用单个查询。
    • 巧妙地避免在桌子周围循环。我想知道它是否可以变得更具可读性
    • 如果是我,我会把它藏在一个函数里。然后你会有 UPDATE myTable SET myTextColumn = dbo.ReduceSpaces(myColumnText) WHERE... 然后你可以在函数中放置任何解释性文本。
    • 但众所周知(我希望),标量函数无法优化,所以我们都避免使用它们(我希望!)
    • 呵呵...嗯,这有点取决于您使用它们的目的。
    【解决方案2】:

    这是一个简单的基于集合的方法,通过应用三个替换将多个空格折叠成一个空格。

    DECLARE @myTable TABLE (myTextColumn VARCHAR(50))
    
    INSERT INTO @myTable VALUES ('0Space')
    INSERT INTO @myTable VALUES (' 1 Spaces 1 Spaces. ')
    INSERT INTO @myTable VALUES ('  2  Spaces  2  Spaces.  ')
    INSERT INTO @myTable VALUES ('   3   Spaces  3   Spaces.   ')
    INSERT INTO @myTable VALUES ('    4    Spaces  4    Spaces.    ')
    INSERT INTO @myTable VALUES ('     5     Spaces  5     Spaces.     ')
    INSERT INTO @myTable VALUES ('      6      Spaces  6      Spaces.      ')
    
    select replace(
              replace(
                 replace(
                    LTrim(RTrim(myTextColumn)), ---Trim the field
                 '  ',' |'),                    ---Mark double spaces
              '| ',''),                         ---Delete double spaces offset by 1
           '|','')                              ---Tidy up
           AS SingleSpaceTextColumn
     from @myTable
    

    您的更新语句现在可以基于:

     update @myTable
        set myTextColumn = replace(
                              replace(
                                 replace(
                                    LTrim(RTrim(myTextColumn)),
                                 '  ',' |'),
                              '| ',''),
                           '|','')  
    

    使用适当的 Where 子句将更新限制为仅包含您需要更新或可能包含双空格的行。

    例子:

    where 1<=Patindex('%  %', myTextColumn)
    

    我找到了关于这种方法的外部文章:REPLACE Multiple Spaces with One

    【讨论】:

    • 我认为这与 Paul 的答案相同,但您的 cmets 使其更具可读性
    • 很明显它们是相同的方法。
    • 外部参考澄清事情
    • 我同意它的措辞更好,更容易理解,但不知何故,感觉就像是在为别人的工作而努力。保罗的回答完全一样。
    • @Lieven :我是根据上面引用的外部参考 Andrew 做出的决定。
    【解决方案3】:
    select 
        string = replace(
                    replace(
                        replace(' select   single       spaces',' ','<>')
                        ,'><','')
                    ,'<>',' ')
    

    Replace duplicate spaces with a single space in T-SQL

    【讨论】:

      【解决方案4】:
      SELECT 'starting...' --sets @@rowcount
      WHILE @@rowcount <> 0
          update myTable
          set myTextColumn = replace(myTextColumn, '  ', ' ')
          where myTextColumn like '%  %'
      

      【讨论】:

        【解决方案5】:

        不是非常基于 SET,但一个简单的 WHILE 就可以了。

        CREATE TABLE #myTable (myTextColumn VARCHAR(32))
        
        INSERT INTO #myTable VALUES ('NoSpace')
        INSERT INTO #myTable VALUES ('One Space')
        INSERT INTO #myTable VALUES ('Two  Spaces')
        INSERT INTO #myTable VALUES ('Multiple    Spaces    .')
        
        WHILE EXISTS (SELECT * FROM #myTable WHERE myTextColumn LIKE '%  %')
          UPDATE  #myTable 
          SET     myTextColumn = REPLACE(myTextColumn, '  ', ' ') 
          WHERE   myTextColumn LIKE '%  %'
        
        SELECT * FROM #myTable
        
        DROP TABLE #myTable
        

        【讨论】:

        • 当然,由于OUTPUT 子句,这在 SQL Server 2000 上不起作用,但答案很好。
        • @Codesleuth - 谢谢,我错过了这个要求。答案已更新为适用于 SQL Server 2000。
        • aww,但是您将其更改为临时表?这让我很伤心,你知道的,2000 年宣布的表格也可以工作!
        • @Codesleuth - 哈哈,不,我不知道。所有 SQL Server 2000 知识都埋藏在我脑海中最黑暗的角落,然后是一些。 OP 可以随时获取原始版本,只需删除 OUTPUT 子句。
        【解决方案6】:

        逐个遍历字符,并保持前一个字符的记录。如果当前字符是空格,而最后一个字符是空格,则stuff它。

        CREATE FUNCTION [dbo].[fnRemoveExtraSpaces]  (@Number AS varchar(1000))
        Returns Varchar(1000)
        As
        Begin
        Declare @n int  -- Length of counter
        Declare @old char(1)
        
        Set @n = 1
        --Begin Loop of field value
        While @n <=Len (@Number)
            BEGIN
             If Substring(@Number, @n, 1) = ' ' AND @old = ' '
              BEGIN
                Select @Number = Stuff( @Number , @n , 1 , '' )
              END
             Else
              BEGIN
               SET @old = Substring(@Number, @n, 1)
               Set @n = @n + 1
              END
            END
        Return @number
        END
        GO
        
        
        select [dbo].[fnRemoveExtraSpaces]('xxx     xxx     xxx    xxx')
        

        【讨论】:

          【解决方案7】:

          这是一个最简单的解决方案:)

              update myTable
              set myTextColumn = replace(replace(replace(LTrim(RTrim(myTextColumn )),' ','<>'),'><',''),'<>',' ')
          

          【讨论】:

            【解决方案8】:
            create table blank(
            field_blank char(100))
            
            insert into blank values('yyy      yyyy')
            insert into blank values('xxxx    xxxx')
            insert into blank values ('xxx    xxx')
            insert into blank values ('zzzzzz zzzzz')
            
            update blank 
            set field_blank = substring(field_blank,1,charindex(' ',field_blank)-1) + ' ' + ltrim(substring(field_blank,charindex(' ',field_blank) + 1,len(field_blank)))
            where CHARINDEX (' ' , rtrim(field_blank)) > 1
            
            select * from blank
            

            【讨论】:

            • @ck:我有兴趣看到 sql 中的循环。您能否发布更新您的答案。 tia。
            【解决方案9】:

            对我来说,上述示例几乎起到了作用,但我需要一些更稳定且独立于表或列或一组迭代次数的东西。所以这是我对上述大多数查询的修改。

            CREATE FUNCTION udfReplaceAll 
            (
                @OriginalText NVARCHAR(MAX),
                @OldText NVARCHAR(MAX),
                @NewText NVARCHAR(MAX)
            )
            RETURNS NVARCHAR(MAX)
            AS
            BEGIN
                WHILE (@OriginalText LIKE '%' + @OldText + '%')
                BEGIN
                    SET @OriginalText = REPLACE(@OriginalText,@OldText,@NewText)
                END
            
                RETURN @OriginalText
            END
            GO
            

            【讨论】:

              【解决方案10】:

              比方说,你的数据是这样的

              Table name : userdata Field: id, comment, status, 
              
               id,  "I love -- -- - -spaces  -- -    my INDIA" , "Active" <br>
               id,  "I love -- -- - -spaces  -- -    my INDIA" , "Active" <br>
               id,  "I love -- -- - -spaces  -- -    my INDIA" , "Active" <br>
               id,  "I love -- -- - -spaces  -- -    my INDIA" , "Active" <br>
              

              就这样吧

              update userdata set comment=REPLACE(REPLACE(comment," ","-SPACEHERE-"),"-SPACEHERE"," ");
              

              我没有测试过,但我认为这会起作用。

              【讨论】:

                【解决方案11】:

                试试这个:

                UPDATE Ships
                SET name = REPLACE(REPLACE(REPLACE(name, '  ', ' ' + CHAR(1)), CHAR(1) + ' ', ''), CHAR(1), '')
                WHERE name LIKE '%  %'
                

                【讨论】:

                  【解决方案12】:
                  REPLACE(REPLACE(REPLACE(myTextColumn,' ',' %'),'% ',''),'%','')
                  

                  上面的语句非常适合用单个空格替换多个空格。 (可选)添加 LTRIMRTRIM 以删除开头的空格。

                  从这里得到它:http://burnignorance.com/database-tips-and-tricks/remove-multiple-spaces-from-a-string-using-sql-server/

                  【讨论】:

                    【解决方案13】:
                    WHILE
                     (SELECT count(myIDcolumn) 
                      from myTable where myTextColumn like '%  %') > 0
                    BEGIN
                      UPDATE myTable 
                      SET myTextColumn = REPLACE(myTextColumn ,'  ',' ')
                    END
                    

                    【讨论】:

                      【解决方案14】:

                      试试看:

                      CREATE OR REPLACE FUNCTION REM_SPACES (TEXTO VARCHAR(2000))
                      
                          RETURNS VARCHAR(2000)
                      
                          LANGUAGE SQL
                      
                          READS SQL DATA
                      BEGIN
                      
                          SET TEXTO = UPPER(LTRIM(RTRIM(TEXTO)));
                      
                          WHILE LOCATE('  ',TEXTO,1) >= 1 DO
                              SET TEXTO = REPLACE(TEXTO,'  ',' ');
                          END WHILE;
                      
                      RETURN TEXTO;
                      
                      END
                      

                      【讨论】:

                        【解决方案15】:
                        Update myTable set myTextColumn = replace(myTextColumn, '  ', ' ');
                        

                        上面的查询将删除所有的双空格和一个空格

                        但这只会工作一次。

                        【讨论】:

                        • @cjk 它在答案中明确提到,它只会工作一次。
                        • 问题中明确提到了OP希望用单个空格替换REPEATING空格。问题中的示例甚至包含您作为答案发布的 SQL,并且她有一个循环 (WHILE) 来重复执行双对单替换。顺便说一句,我没有投反对票。
                        猜你喜欢
                        • 2011-01-28
                        • 2011-01-05
                        • 2013-12-02
                        • 1970-01-01
                        • 2013-07-03
                        • 2013-11-25
                        • 1970-01-01
                        • 2015-03-27
                        相关资源
                        最近更新 更多