У меня есть источник данных, который содержит данные в полях с разделителями, которые существуют в промежуточной области в SQL Server. Я хотел бы преобразовать эти данные во множество строк, чтобы с ними было легче работать. Это отличается от множества других вопросов и ответов по аналогичным темам тем, что у меня есть несколько полей, в которых существуют эти данные с разделителями. Вот пример того, как выглядят мои данные:
ID | Field | Value
---+-------+------
1 | a,b,c | 1,2,3
2 | a,c | 5,2
И это желаемый результат:
ID | Field | Value
---+-------+------
1 | a | 1
1 | b | 2
1 | c | 3
2 | a | 5
2 | c | 2
Мой код до сих пор использует метод синтаксического анализа XML, подобный упомянутому здесь: строка, разделенная запятыми, на отдельные строки. Мне нужно было расширить ее, чтобы соединить каждое поле с соответствующим значением, что я сделал, создав row_number для каждого идентификатора, а затем сопоставив его на основе идентификатора и этого row_number.
Моя проблема в том, что это мучительно медленно, поэтому мне интересно, есть ли у кого-нибудь более эффективные методы?
select
[Value].ID, [Field], [Value]
from
(select
A.ID, Split.a.value('.', 'varchar(100)') as [Value],
row_number() over (partition by ID order by Split.a) as RowNumber
from
(select
ID, cast('<M>' + replace([Value], ',', '</M><M>') + '</M>' as xml) as [Value]
from
#source_table
where
[Field] not like '%[<>&%]%' and [Value] not like '%[<>&%]%') as A
cross apply
[Value].nodes ('/M') as Split(a)
) [Value]
inner join
(
select
A.ID, Split.a.value('.', 'varchar(100)') as [Field],
row_number() over (partition by A.ID order by Split.a) as RowNumber
from
(select
ID, cast('<M>' + replace([Field], ',', '</M><M>') + '</M>' as xml) as [Field]
from
#source_table
where
[Field] not like '%[<>&%]%' and [Value] not like '%[<>&%]%') as A
cross apply
[Field].nodes ('/M') as Split(a)
) [Field] on [Value].ID = [Field].ID and [Value].RowNumber = [Field].RowNumber