将嵌入式CSV文本拆分为单独的行

时间:2019-02-17 14:23:33

标签: sql-server csv sql-server-2008 delimited

我正在尝试将逗号分隔的数据拆分为单独的列(使用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((从myTable中选择TOP 1个内容,CHAR(10))

结果:

1,John,Doe
2,Jane,Doe

使用子字符串功能,我只能返回每条记录的第一行:

SELECT dateRetrieved,SUBSTRING(content,1,CHARINDEX(CHAR(10),content)-1)作为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 :(得分:1)

交叉应用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