Разделить встроенный текст CSV на отдельные строки - PullRequest
0 голосов
/ 17 февраля 2019

Я пытаюсь разбить данные через запятую на отдельные столбцы (используя SQL Server 2008).Я встречал подобные вопросы здесь, но в моем случае данные, содержащиеся в каждой строке, ОБА разделены запятыми и символами возврата каретки.

ПРИМЕР:

Date              Content
----              -------
1/1/2019          1, John, Doe
                  2, Jane, Doe

1/2/2019          1, John, Doe
                  2, Jane Doe
                  3, Mary, Smith

Использованиепользовательская функция разделения, я смог вернуть значение только для одной записи:

SELECT * FROM Split_CTE ((ВЫБРАТЬ ТОП 1 содержимого из myTable), CHAR (10))

RESULT:

1,John,Doe
2,Jane,Doe

И используя функцию подстроки, я смог вернуть только первую строку из каждой записи:

SELECT dateRetrieved, SUBSTRING (content, 1, CHARINDEX (CHAR (10),content) -1) as Row FROM myTable

РЕЗУЛЬТАТ:

1/1/2019    1,John,Doe
1/2/2019    1,John,Doe

Но что я пытаюсь получить, это:

Date     Row   First   Last
1/1/2019 1     John    Doe
1/1/2019 2     Jane    Doe
1/2/2019 1     John    Doe
1/2/2019 2     Jane    Doe
1/2/2019 3     Mary    Smith

Есть предложения?

1 Ответ

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

Перекрестное применение B разделит с помощью разделителя CRLF

Перекрестное применение C с анализом строки с запятой из B в столбцы

Следует отметить, что каждый из CROSS APPLY можно преобразовать вTVF

Пример

Select A.Date
      ,C.*
 From  YourTable A
 Cross Apply (
                Select RetSeq = row_number() over (order by 1/0)
                      ,RetVal = ltrim(rtrim(B.i.value('(./text())[1]', 'varchar(max)')))
                From  (Select x = Cast('<x>' + replace((Select replace([Content],char(13)+char(10),'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A 
                Cross Apply x.nodes('x') AS B(i)
             ) B
 Cross Apply (
                Select Pos1 = ltrim(rtrim(xDim.value('/x[1]','varchar(max)')))
                      ,Pos2 = ltrim(rtrim(xDim.value('/x[2]','varchar(max)')))
                      ,Pos3 = ltrim(rtrim(xDim.value('/x[3]','varchar(max)')))
                From  (Select Cast('<x>' + replace((Select replace(B.RetVal,',','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml) as xDim) as A 
             ) C
 Order by A.Date,C.Pos1

Возвращает

Date        Pos1    Pos2    Pos3
2019-01-01  1       John    Doe
2019-01-01  2       Jane    Doe
2019-01-02  1       John    Doe
2019-01-02  2       Jane    Doe
2019-01-02  3       Mary    Smith
...