如何在字符串之间插入逗号

Posted

技术标签:

【中文标题】如何在字符串之间插入逗号【英文标题】:How to insert a comma in between a string 【发布时间】:2019-05-09 07:52:35 【问题描述】:

我有一个字符串,我需要在给定的字符串之间插入一个逗号。请帮我出出主意

declare @a varchar(15) = 'asdfghj'
select @a

我希望输出为'a,s,d,f,g,h,j'

【问题讨论】:

一开始就不要在 SQL 中这样做。 SQL这种语言在字符串操作方面非常差。为什么你首先要这样做?你想做什么,这个字符串是从哪里来的?也许有更好的方法来做任何你想做的事情,而不涉及字符串操作 递归 cte? 下面的答案可能会对您有所帮助,但无论您使用什么,它都会显着降低您的查询速度。为什么不在应该完成的表示层中执行此操作 我想很多人都有这个确切的问题。我不同意关闭的建议,也不同意所有的反对票。我希望这包含在 sql server 2016 的 string_split 中 【参考方案1】:

这将在 sql server 2008 中工作

DECLARE @a varchar(max)='23'
DECLARE @b INT=len(@a)

WHILE @b>1
SELECT @a=stuff(@a,@b,0,','),@b-=1

SELECT @a

如果你曾经升级到 sql server 2017,你可以使用这个版本,假设字符串不超过 2047 个字符(2047 是 spt_values 中 type=P 的最大数字,否则你可以使用数字表或类似的东西):

DECLARE @a varchar(max)='abcd'

SELECT string_agg(substring(@a,number+1,1),',')
FROM master..spt_values
WHERE number < len(@a)
and type='P'

【讨论】:

【参考方案2】:

SQL Server 并非设计用于执行此操作,但这里有一种在 while 循环中执行此操作的简单方法;

    DECLARE @a varchar(15) = 'asdfghj'
    DECLARE @i int = 1
    DECLARE @output varchar(30)

    WHILE (@i <= len(@a))
    BEGIN
        SET @output = ISNULL(@output,'') + ',' + SUBSTRING(@a, @i, 1)
        SET @i = @i + 1
    END

    SET @output = STUFF(@output,1,1,'')

    SELECT @output

输出:a,s,d,f,g,h,j

它接受输入的每个单独字符并在其前面插入一个逗号。 STUFF 函数会删除字符串中的第一个逗号,如果您愿意,可以使用 SUBSTRINGRIGHT 来执行此操作。

如果您调整 @a 和 @output 的长度,这将适用于您传入的任何长度字符串

【讨论】:

您可以使用this 方法稍微改进您的答案(不要告诉任何人)【参考方案3】:

仔细考虑 Panagiotis Kanavos 的评论,但如果您想使用 T-SQL 执行此操作,一种可能的方法是使用递归 CTE 和 FOR XML(受 SQL Server 2008 支持):

DECLARE @a varchar(15) = 'asdfghj'

;WITH cte AS (
    SELECT SUBSTRING(@a, 1, 1) AS Symbol, 1 AS Position
    UNION ALL
    SELECT SUBSTRING(@a, Position + 1, 1), Position + 1
    FROM cte
    WHERE Position < LEN(@a)
)
SELECT STUFF((
    SELECT CONCAT(N',',  Symbol)
    FROM cte
    ORDER BY Position
    FOR XML PATH('')
), 1, 1, N'') AS Result
OPTION (MAXRECURSION 0)

输出:

Result
a,s,d,f,g,h,j

注意事项: 仅供参考,从 SQL Server 2017 开始,您可以使用STRING_AGG():

DECLARE @a varchar(15) = 'asdfghj'

;WITH cte AS (
    SELECT SUBSTRING(@a, 1, 1) AS Symbol, 1 AS Position
    UNION ALL
    SELECT SUBSTRING(@a, Position + 1, 1), Position + 1
    FROM cte
    WHERE Position < LEN(@a)
)
SELECT STRING_AGG(Symbol, ',')
FROM cte
OPTION (MAXRECURSION 0)

【讨论】:

【参考方案4】:

正如已经提到的,这是一个糟糕的主意。

如果可以避免,请不要在 SQL Server 中执行此操作。

也就是说,如果由于某种原因无法避免,则基于集合的解决方案将涉及数字表。如果您没有其中之一,您可以使用cte 以很少的开销生成一个。要仅使用一个值,您可以这样做:

declare @a varchar(15) = 'asdfghj';

with t(t)as(select t from(values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1))as t(t))
    ,n(n)as(select top(len(@a)) row_number()over(order by(select null)) from t,t t2,t t3,t t4)
select @a = stuff((select ',' + substring(@a,n,1)
                   from n
                   order by n
                   for xml path('')
                  )
                 ,1,1,''
                 );

select @a;

哪个输出:a,s,d,f,g,h,j

或者将此逻辑应用于值表,您可以执行以下操作:

declare @t table (a varchar(100));
insert into @t values('asdfghj'),('qwerty'),('qwertyuiopasdfghjklzxcvbnm[];#?|');

with t(t)as(select t from(values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1))as t(t))
    ,n(n)as(select top(select max(len(a)) from @t) row_number()over(order by(select null)) from t,t t2,t t3,t t4)
select stuff((select ',' + substring(a,n,1)
              from n
              where n.n <= len(t.a)
              order by n.n
              for xml path('')
             )
            ,1,1,''
            ) as CommaDelimited
from @t as t;

哪些输出:

+---------------------------------------------------------------------------+
|                              CommaDelimited                               |
+---------------------------------------------------------------------------+
| a,s,d,f,g,h,j                                                             |
| q,w,e,r,t,y                                                               |
| q,w,e,r,t,y,u,i,o,p,a,s,d,f,g,h,j,k,l,z,x,c,v,b,n,m,[,],;,#,?,|           |
+---------------------------------------------------------------------------+

【讨论】:

【参考方案5】:

希望这可行,我使用 STUFF() 函数插入 ,

    declare @a varchar(15) = 'asdfghj'
    declare @totalchar int = len(@a)
    declare @counter int = @totalchar

    while @counter >=1
    begin 
            if @counter + 1 <= @totalchar
            begin
                 set @a = stuff(@a,@counter + 1, 0 , ',')
            end
            set @counter = @counter -1
    end

    select @a

【讨论】:

【参考方案6】:

我非常同意 Panagiotis Kanavos 的评论。以下 sn-p 将为您工作。

Declare @a varchar(15) = 'asdfghj',@OUTPUT VARCHAR(MAX)= ''

SELECT @OUTPUT = @OUTPUT+AA+',' FROM (
SELECT number ,SUBSTRING(@a, number, 1) AA
FROM master.DBO.spt_values WHERE TYPE = 'P'
AND number BETWEEN 1 AND LEN(@a)
)A
Order by number

SELECT SUBSTRING(@OUTPUT,1,LEN(@OUTPUT)-1)

我使用了spt_values,这是微软未记录的,不是首选。您可以尝试使用 Numbers 表进行相同的操作。

【讨论】:

【参考方案7】:

试试这个简单的方法...

DECLARE @INPUT VARCHAR(10) = 'ABCD'
DECLARE @i INT = 1
DECLARE @OUTPUT VARCHAR(50) = ''

WHILE @I < = LEN(@INPUT)
BEGIN
    SET @OUTPUT = @OUTPUT + SUBSTRING(@INPUT,@i,1) + ','
    SET @i = @i + 1
END
SET @OUTPUT = SUBSTRING(@OUTPUT,1,LEN(@OUTPUT) - 1)
PRINT @OUTPUT

【讨论】:

复制别人的答案并重新发布并进行非常小的更改通常被认为是不好的形式。 亲爱的@Rich Benner。这是我自己的代码。我没有抄兄弟。

以上是关于如何在字符串之间插入逗号的主要内容,如果未能解决你的问题,请参考以下文章

如何在数字字符串中插入逗号以分隔零? [复制]

如何在两个逗号之间获取字符串

如何使用Java为列表中的每个字符串添加或插入'(单引号),其中字符串用逗号分隔

请问如何在Oracle中截取第一个逗号和第二个逗号之间的字符串

如何在每个字符串之间用逗号分割数组?

php如何将逗号分隔的多个json格式的字符串作为一个值插入到mysql表中? [复制]