Разбить номер строки типа на список символов

#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;