Как вставить запятую между строк - PullRequest
0 голосов
/ 09 мая 2019

У меня есть строка, и мне нужно вставить запятую между данной строкой.Пожалуйста, помогите мне с некоторыми идеями

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

Я ожидаю, что выход 'a,s,d,f,g,h,j'

Ответы [ 7 ]

1 голос
/ 09 мая 2019

Это будет работать в 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'
0 голосов
/ 09 мая 2019

Надеюсь, это работает, я использовал функцию 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
0 голосов
/ 09 мая 2019

Как уже упоминалось, это ужасная идея.

Не делайте этого в 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,[,],;,#,?,|           |
+---------------------------------------------------------------------------+
0 голосов
/ 09 мая 2019

Попробуйте этот простой метод ...

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
0 голосов
/ 09 мая 2019

Внимательно рассмотрите комментарий Панагиотиса Канавоса, но если вы хотите сделать это с 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)
0 голосов
/ 09 мая 2019

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 удаляет самую первую запятую в строке, вы можете сделать это с помощью SUBSTRING или RIGHT, если хотите.

Это будет работать с любой строкой длины, которую вы передадите, если вы настроите длину @a и @ output

0 голосов
/ 09 мая 2019

Я полностью согласен с комментарием Panagiotis Kanavos. Ниже фрагмент будет работать для вас.

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, что недокументировано Microsoft, что не является предпочтительным. Вместо этого вы можете попробовать то же самое с таблицей чисел.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...