Разделение строки SQL Server на столбец - PullRequest
0 голосов
/ 05 февраля 2019

У меня есть функция, которая принимает поле VARCHAR, которое мне затем нужно проанализировать и сгруппировать в отдельные столбцы.

Ниже приведен пример входных данных:

@input_data = '109.1|1|3.3|5.7|7.9,106.2|2|2.5|2.5|3.0,126.4.2|3|8.2|6.4|3.9'

Выходные данныеданные должны выглядеть следующим образом:

ID        SEQ   SCORE1   SCORE2   SCORE3
109.1     1     3.3      5.7      7.9
106.2     2     2.5      2.5      3.0
126.4.2   3     8.2      6.4      3.9

Как видите, я использую запятую для разделения входных данных и деления их на строки.Но моя проблема действительно возникает, когда я пытаюсь разбить данные каждой строки на соответствующие столбцы.Я понимаю, что могу использовать PARSENAME для этого, но меня беспокоит использование точки в поле ID и в полях SCORE.

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

 SELECT PARSENAME(REPLACE(ms.value, '|', '.'), 5) AS ID,
        PARSENAME(REPLACE(ms.value, '|', '.'), 4) AS SEQ,
        PARSENAME(REPLACE(ms.value, '|', '.'), 3) AS SCORE1,
        PARSENAME(REPLACE(ms.value, '|', '.'), 2) AS SCORE2, 
        PARSENAME(REPLACE(ms.value, '|', '.'), 1) AS SCORE3   
 FROM   string_split(@input_data , ',') ms

1 Ответ

0 голосов
/ 05 февраля 2019

Вот один из способов сделать это.Я использую DelimitedSplit8K от Джеффа Модена, который вы можете найти здесь.http://www.sqlservercentral.com/articles/Tally+Table/72993/ Самым большим преимуществом этого разделителя является порядковая позиция, которая отсутствует в string_split.

Обратите внимание, как сначала нужно разделить запятые, а затем снова на трубы.Наконец, вы должны использовать условную агрегацию, чтобы объединить все это.Для пары строк это не страшно, но передача табличного параметра в миллион раз эффективнее, чем разбор строк для повторной сборки в потребляемые данные.

declare @input_data varchar(200) = '109.1|1|3.3|5.7|7.9,106.2|2|2.5|2.5|3.0,126.4.2|3|8.2|6.4|3.9'

select ID = max(case when x2.ItemNumber = 1 then x2.Item end)
    , SEQ = max(case when x2.ItemNumber = 2 then x2.Item end)
    , SCORE1 = max(case when x2.ItemNumber = 3 then x2.Item end)
    , SCORE2 = max(case when x2.ItemNumber = 4 then x2.Item end)
    , SCORE3 = max(case when x2.ItemNumber = 5 then x2.Item end)
from dbo.DelimitedSplit8K(@input_data, ',')x
cross apply dbo.DelimitedSplit8K(x.item, '|') x2
group by x.ItemNumber
...