在MS SQL中用单个逗号替换多个逗号

时间:2018-06-06 06:56:55

标签: sql sql-server regex string tsql

如何在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的问题。

8 个答案:

答案 0 :(得分:8)

您可以使用简单的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 /...一起使用。

答案 1 :(得分:3)

使用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

答案 2 :(得分:2)

虽然有很好的答案(我个人倾向于喜欢2025)但我想发布另一种方法(尤其是作为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()]会将节点减少为包含内容的节点。它们将使用附加的逗号重新创建。带有.value() XPath的{​​{1}}将返回XML中所有内容的单个字符串。

答案 3 :(得分:0)

请使用

    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;

答案 4 :(得分:0)

尝试使用此脚本删除空格,多个逗号并将单个逗号分隔为结果

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

答案 5 :(得分:0)

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

假设您有一个包含T列的表c also see working demo

解释内联为注释

/* 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 

答案 6 :(得分:0)

这就是我所做的。

select replace(replace(replace(replace('a ,,, b ,,, c,d,e ,,,, f',',','<>'),'> <',''), '<>',',')

答案 7 :(得分:0)

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

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

输出:

LE, EN, A