【问题标题】:Replacing multiple commas with single comma in MS SQL在 MS SQL 中用单个逗号替换多个逗号
【发布时间】:2018-06-06 06:56:54
【问题描述】:

如何在 MS SQL 中用单个逗号替换列中的连续逗号?

例如,我有类似的数据

 a,,,,b,,,c,,,,,,
 d,e,,,f,,,,,,g,,  

我希望将其处理为以下格式:

 a,b,c,
 d,e,f,g,

建议的副本Use SQL to Replace Multiple Commas in a String with a Single Comma 用于Oracle。这是一个关于 SQL Server 的问题。

【问题讨论】:

标签: sql sql-server regex string tsql


【解决方案1】:

你可以使用简单的REPLACE:

SELECT c, REPLACE(REPLACE(REPLACE(c, ',', '~,'), ',~', ''), '~,', ',')
FROM tab;

DBFiddle Demo

输出:

┌──────────────────┬──────────┐
│        c         │  result  │
├──────────────────┼──────────┤
│ a,,,,b,,,c,,,,,, │ a,b,c,   │
│ d,e,,,f,,,,,,g,, │ d,e,f,g, │
└──────────────────┴──────────┘

请注意,这种方法不依赖于 SQL 方言,应该适用于 MySQL/Oracle/PostgreSQL/...

【讨论】:

    【解决方案2】:

    使用 CTE 很容易做到:

    declare @s varchar(20) = 'a,,,,b,,,c,,,,,, d,e,,,f,,,,,,g,,'
    
    ;with cte as (
        select replace(@s, ',,', ',') [s], 1 [rn]
        union all
        select replace(s, ',,', ',') [s], [rn] + 1
        from cte
        where LEN(s) - LEN(replace(s, ',,', '')) > 0
    )
    
    select top 1 @s = s from cte
    order by rn desc
    
    select @s
    

    【讨论】:

      【解决方案3】:

      虽然有很好的答案(我个人倾向于 lad2025)我想发布另一种方法(特别是作为 DruvJoshi 答案的扩展)

      DECLARE @tbl TABLE(s VARCHAR(100))
      INSERT INTO @tbl VALUES('d,e,,,f,,,,,,g,,')
                            ,('a,,,,b,,,c,,,,,,');
      
      SELECT CAST('<x>'+REPLACE(s,',','</x><x>')+'</x>' AS XML)
                    .query('for $x in /x[text()]
                            return
                            <x>
                            {
                            concat($x, ",")
                            }
                            </x>
                            ')
                    .value('.','nvarchar(max)') AS result
      FROM @tbl;
      

      简短说明:

      该解决方案使用众所周知的 XML 技巧来拆分字符串。其余的是XQuery。谓词/x[text()] 会将节点减少为具有内容的节点。它们将在附加逗号的情况下重新创建。带有XPath..value() 将返回XML 中所有内容的单个字符串。

      【讨论】:

        【解决方案4】:

        请使用

            SELECT 
                REGEXP_REPLACE(
                    REGEXP_REPLACE('Hi,,How are you? Fine, thanks ,, ,  ,,,, , James,Arden.', ', | ,', ','), --Replace ', ' and ' ,' with ','
                ',{1,}', ', ') single_comma_text --Replace one or more comma with comma followed by space
        FROM DUAL;
        

        【讨论】:

          【解决方案5】:

          试试这个脚本,它消除了空格、多个逗号并给出单个逗号分隔的结果

          DECLARE @tbl AS TABLE (data nvarchar(max))
          INSERT INTO @tbl
          SELECT 'a,,,,b,,,c,,,,,,  ,,,,  ,,,   ,, ,,,,,d,,,,,,,,      ,, d,e,,,f,,,,,,g,,'
          
          ;WITH CTE
          AS
          (
          SELECT data
                 ,CAST(LEFT(data,1) AS VARCHAR(10)) AS Letter
                 ,RIGHT(Data,LEN(Data)-1) AS Remainder
          FROM @tbl
          WHERE LEN(data)>1   
          UNION ALL
          SELECT data
                 ,CAST(LEFT(Remainder,1) AS VARCHAR(10)) AS Letter
                 ,RIGHT(Remainder,LEN(Remainder)-1) AS Remainder
          FROM CTE
          WHERE LEN(Remainder)>0
          )
          SELECT STUFF((SELECT ', '+ Letter 
          FROM
          (
           SELECT Letter
           FROM CTE
           WHERE Letter <>',' AND Letter <>''
          )dt FOR XML PATH ('')),1,1,'')  AS RequiredOutPut 
          

          结果

          RequiredOutPut
          ------------------
           a, b, c, d, d, e, f, g
          

          演示:http://rextester.com/VEZS31565

          【讨论】:

            【解决方案6】:

            如果您可以使用未知数量的逗号,我建议您使用 XML 路径进行拆分,如下所示。

            假设您有一个表 T 与列 c also see working demo

            解释是内联的 cmets

            /* first we split out each letter from each column using XML Path after replacing commas with empty nodes */
            ; with cte as (
            select
            id,s 
            from 
            (
                select 
                    id, 
                    xmldata=cast('<x>'+replace(c,',','</x><x>')+'</x>' as xml) -- conversion to XML from varchar
                from t
             )A
            cross apply
            ( 
                select 
                   s = data.D.value('.','varchar(100)')
                     FROM 
                  A.xmldata.nodes('x') AS data(D)
            
             )c
             where s <>''-- filter out empty nodes i.e. commas
                )
              /* Now we join back results from CTE by adding single comma between letters*/
              select distinct id, stuff
              ((select ','+ s 
                from cte c1 
                where c1.id =c2.id
                for xml path ('')),1,1,'')
                  from cte c2 
            

            【讨论】:

            • @Shnugo 我喜欢它。我不知道Xquery,但你的回答是我熟悉它的动力。谢谢!
            【解决方案7】:

            这就是我所做的。

            选择替换(替换(替换('a,,,b,,,c,d,e,,,,f',',',''),'>',',')

            【讨论】:

              【解决方案8】:

              这是满足以下所有情况的简单方法:

              1. 删除字符串开头的多个逗号
              2. 删除字符串末尾的多个逗号
              3. 将字符串中间的多个逗号删除为单个逗号
              select  REGEXP_REPLACE(REGEXP_REPLACE(',,LE,,EN,,A,,,','^,*|,*$',''),',{1,}', ', ');
              

              输出:

              LE, EN, A
              

              【讨论】:

                猜你喜欢
                • 2017-06-20
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-04-25
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多