如何在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的问题。
答案 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
答案 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)
这是满足以下所有情况的简单方法:
select REGEXP_REPLACE(REGEXP_REPLACE(',,LE,,EN,,A,,,','^,*|,*$',''),',{1,}', ', ');
输出:
LE, EN, A