TSQL:如何在字符串中的每个字符之间插入分隔符

时间:2017-12-26 03:20:35

标签: sql-server tsql

我有一个这样的字符串:

Apple

我想在每个字符后面加一个分隔符,以便最终结果如下:

A,p,p,l,e

在C#中,我们使用一种线性方法来实现上述Regex.Replace('Apple', ".{1}", "$0,");

我只能想到用charindex循环每个字符来附加分隔符但看起来有点复杂。是否有任何优雅的方式和更简单的方法来实现这一目标?

5 个答案:

答案 0 :(得分:2)

感谢HABO的建议。我能够使用代码生成我想要的结果,但需要花一点时间来真正理解代码的工作原理。

经过一番搜索,我设法找到一篇有用的文章,在每个角色之间插入空格,让我更容易理解。

我稍微修改代码以定义并包含欲望分隔符,而不是将其固定到空格作为分隔符:

 DECLARE @pos INT = 2 -- location where we want first space 
 DECLARE @result VARCHAR(100) = 'Apple'
 DECLARE @separator nvarchar(5) = ','
    WHILE @pos < LEN(@result)+1 
    BEGIN 
        SET @result = STUFF(@result, @pos, 0, @separator); 
        SET @pos = @pos+2; 
    END 
    select @result; -- Output: A,p,p,l,e

Reference

答案 1 :(得分:0)

一种丑陋的方法是将字符串拆分为字符,理想情况下使用数字表,然后使用所需的分隔符重新组合。

效率较低的实现在CTE中使用递归来分割字符并在字符对之间插入分隔符:

declare @Sample as VarChar(20) = 'Apple';
declare @Separator as Char = ',';

with Characters as (
  select 1 as Position, Substring( @Sample, 1, 1 ) as Character
  union all
  select Position + 1,
    case when Position & 1 = 1 then @Separator else Substring( @Sample, Position / 2 + 1, 1 ) end
    from Characters
    where Position < 2 * Len( @Sample ) - 1 )
  select Stuff( ( select Character + '' from Characters order by Position for XML Path( '' ) ), 1, 0, '' ) as Result;

您可以将select Stuff...行替换为select * from Characters;以查看正在发生的事情。

答案 2 :(得分:0)

试试这个

declare @var varchar(50) ='Apple'

;WITH CTE
AS
(
    SELECT
        SeqNo = 1,
        MyStr = @var,
        OpStr = CAST('' AS VARCHAR(50))

    UNION ALL

    SELECT
        SeqNo = SeqNo+1,
        MyStr = MyStR,
        OpStr = CAST(ISNULL(OpStr,'')+SUBSTRING(MyStR,SeqNo,1)+',' AS VARCHAR(50))
        FROM CTE
        WHERE SeqNo <= LEN(@var)
)
SELECT
    OpStr = LEFT(OpStr,LEN(OpStr)-1)
    FROM CTE
        WHERE SeqNo = LEN(@Var)+1

答案 3 :(得分:0)

在下面的SQL脚本中,我使用带有数字表的SUBSTRING()函数获取每个字符(为了简单起见,我在这里使用了spt_values视图)然后我通过两种不同的方法连接它们,你可以选择一个

如果您使用的是SQL Server 2017,我们会有一个新的SQL string aggregation function 第一个脚本使用string_agg函数

declare @str nvarchar(max) = 'Apple'

SELECT
string_agg( substring(@str,number,1) , ',') Within Group (Order By number)
FROM master..spt_values n
WHERE 
Type = 'P' and 
Number between 1 and len(@str)

如果您使用的是以前的版本,可以使用string concatenation using FOR XML Path和SQL Stuff功能,如下所示

declare @str nvarchar(max) = 'Apple'

; with cte as (
    SELECT
    number,
    substring(@str,number,1) as L
    FROM master..spt_values n
    WHERE 
    Type = 'P' and 
    Number between 1 and len(@str)
)
SELECT
  STUFF(
    (
    SELECT
      ',' + L
    FROM cte
    order by number
    FOR XML PATH('')
    ), 1, 1, ''
  )

两种解决方案都会产生相同的结果,我希望它有所帮助

enter image description here

答案 4 :(得分:0)

如果您有SQL Server 2017和ngrams8k的副本,那么它非常简单:

declare @word varchar(100) = 'apple';

select newString = string_agg(token, ',') within group (order by position)
from dbo.ngrams8k(@word,1);

对于2017年之前的系统,它几乎一样简单:

declare @word varchar(100) = 'apple';

select newstring = 
( select token + case len(@word)+1-position when 1 then '' else ',' end
  from dbo.ngrams8k(@word,1)
  order by position
  for xml path(''))