В следующий раз, пожалуйста, укажите версию SQL -Server ...
Следующее решение работает практически с любой версией, если у вас версия v2016 +, возможно, есть более подходящие подходы. Попробуйте это:
DECLARE @TEXT VARCHAR(60) = '1/10/2/20/3/30/4/40';
WITH Casted(ToXml) AS
(
SELECT CAST('<x>' + REPLACE(@TEXT,'/','</x><x>') + '</x>' AS XML)
)
,TallyOddNumbers(OddNumber) AS
(
SELECT TOP((SELECT ToXml.value('count(/x)','int')/2 FROM Casted)) (ROW_NUMBER() OVER(ORDER BY (SELECT NULL)))*2-1 FROM master..spt_values
)
SELECT ToXml.value('/x[sql:column("OddNumber")][1]','int') AS Col1
,ToXml.value('/x[sql:column("OddNumber")+1][1]','int') AS Col1
FROM Casted
CROSS JOIN TallyOddNumbers;
Идея вкратце:
- Первый cte "Casted" создаст XML из вашей строки.
- The второй cte "TallyOddNumbers" будет использовать
ROW_NUMBER()
против master..spt_values
(здесь можно использовать любой больший набор) для создания набора работающих нечетных чисел - В вычисленном предложении
TOP
будет использоваться XML.value()
с count()
, чтобы найти необходимое количество пар элементов. - В последнем запросе будет использоваться подсчет для получения значений по их позициям.
Подсказка: Вы можете использовать приведенный выше код просто вместе с INSERT
, чтобы получить набор в постоянной таблице.
ОБНОВЛЕНИЕ для версии 2016 +
В своем собственном ответе вы используете string_split()
(что не очень хорошая идея из-за негарантированного порядка сортировки). Но это указывает на версию v2016 +.
Вы можете попробовать этот альтернативный подход
DECLARE @TEXT VARCHAR(60) = '1/10/2/20/3/30/4/40';
WITH ToJson(j) AS(SELECT CONCAT('[',REPLACE(@TEXT,'/',','),']'))
SELECT p.Col1
,p.Col2
FROM
(
SELECT A.[key] /2 AS GroupIndex
,CONCAT('Col',A.[key]%2 +1) AS ColumnName
,A.[value] AS TheValue
FROM ToJson
CROSS APPLY OPENJSON(j) A
) t
PIVOT
(
MAX(TheValue) FOR ColumnName IN(Col1,Col2)
) p;
Идея вкратце:
- Cte преобразует ваш CSV -лист к массиву JSON
- Мы используем
OPENJSON
для чтения этого массива key
- позиция элементов. Вместе с %2
(оператором по модулю) мы получаем вычисляемое переменное имя столбца - Наконец, мы можем использовать
PIVOT
для разбивки ваших значений на Col1
и Col2
. - .
A.[key] /2
будет использовать трюк с целочисленными делениями для создания одного числа на группу (в противном случае вы увидите только последний ряд).