#sql #sql-server #tsql
#sql #sql-сервер #tsql
Вопрос:
У меня есть столбец, в котором есть буквенно-цифровые строки, подобные 123x758v961j
.
Мне нужно разделить это буквенно-цифровое число на символы с пробелом между значениями.
Пример: 123x758v961j
=====> 1 2 3 x 7 5 8 v 9 6 1 j
Мне нужна функция, которая возвращает это решение.
Комментарии:
1. Это было закрыто как дубликат, но связанный вопрос предлагал просто устаревшие подходы с использованием
WHILE
циклов… Проголосовали за повторное открытие вопроса…
Ответ №1:
Используя NGrams8K
для разбиения строки на отдельные символы, а затем «классическое» решение FOR XML PATH
и STUFF
для объединения символов обратно, вы можете сделать это:
SELECT V.S,
STUFF((SELECT ' ' NG.token
FROM dbo.NGrams8k(V.S,1) NG
ORDER BY NG.position
FOR XML PATH(''),TYPE).value('.','varchar(100)'),1,1,'') AS S2 --Use a varchar length that is double(-1) then length of your actual data type here
FROM (VALUES('123x758v961j'))V(S);
Ответ №2:
Просто другой способ
CREATE FUNCTION dbo.SplitToChars(
@String NVARCHAR(300)
)
RETURNS NVARCHAR(300)
AS
BEGIN
DECLARE @Result NVARCHAR(300) = '';
WITH CTE AS
(
SELECT 1 N
UNION ALL
SELECT N 1
FROM CTE
WHERE N < LEN(@String)
)
SELECT @Result = CONCAT(@Result, SUBSTRING(@String, N, 1), N' ')
FROM CTE;
RETURN (RTRIM(@Result));
END;
Затем просто SELECT dbo.SplitToChars(N'123x758v961j')
ВОЗВРАТ:
1 2 3 x 7 5 8 v 9 6 1 j
Ответ №3:
И еще один подход 😉
DECLARE @str VARCHAR(100)='123x758v961j';
WITH Tally(Nmbr) AS
(
SELECT TOP(LEN(@str)) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) FROM master..spt_values
)
SELECT TRIM(
(
SELECT ' ' SUBSTRING(@str,Nmbr,1)
FROM Tally
ORDER BY Nmbr
FOR XML PATH('')
)
);
Идея заключается в том, чтобы использовать подсчет на лету (список текущих чисел для каждой позиции внутри @str
) для чтения символов один за другим. Эта производная таблица пересортирована.
И — просто для развлечения — чтобы продемонстрировать диапазон подходов, еще один, использующий необычное обновление (чего следует избегать на самом деле ;-))
WITH Tally(Nmbr) AS
(
SELECT TOP(LEN(@str)) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) FROM master..spt_values
)
SELECT @str=STUFF(@str,Nmbr,0,' ')
FROM Tally
ORDER BY Nmbr DESC;
SELECT @str;