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

Posted

技术标签:

【中文标题】将嵌入的 CSV 文本拆分为单独的行【英文标题】:Split Embedded CSV Text Into Separate Rows 【发布时间】:2019-07-11 01:31:45 【问题描述】:

我正在尝试将逗号分隔的数据拆分为单独的列(使用 SQL Server 2008)。我在这里看到过类似的问题,但就我而言,每一行中包含的数据都是逗号分隔和回车分隔的。

示例:

日期内容 ---- -------- 1/1/2019 1,约翰,能源部 2,简,多伊 2019 年 1 月 2 日 1,约翰,能源部 2、简·多伊 3、玛丽·史密斯

使用自定义拆分函数,我能够只返回一条记录的值:

SELECT * FROM Split_CTE((SELECT TOP 1 content FROM myTable), CHAR(10))

结果:

1,约翰,多伊 2,简,多伊

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

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

结果:

2019 年 1 月 1 日 1,约翰,多伊 2019 年 1 月 2 日 1,约翰,多伊

但我想要找回的是:

日期行第一最后 2019 年 1 月 1 日 1 约翰·多伊 2019 年 1 月 1 日 2 简·多伊 2019 年 1 月 2 日 1 约翰·多伊 2019 年 1 月 2 日 2 简·多伊 2019 年 1 月 2 日 3 玛丽·史密斯

有什么建议吗?

【问题讨论】:

【参考方案1】:

Cross Apply B 将使用 CRLF 分隔符进行拆分

Cross Apply 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

【讨论】:

非常感谢 - 成功了!当涉及到交叉应用时,我往往会迷失方向——我需要投资一个关于 SQL 高级特性的在线教程。可用于将数据强制转换为看似无穷无尽的格式的内置工具从未停止让我感到惊讶...... @dhughes 乐于助人。我每天都在这里学到新东西...这很有趣。

以上是关于将嵌入的 CSV 文本拆分为单独的行的主要内容,如果未能解决你的问题,请参考以下文章

我可以使用 SQL 将存储为 CSV(逗号分隔值)的表列的内容拆分为新表中的单独行吗?

2 行文本 UIButton

使用Python将单行的文本拆分为CSV文件中同一列的多行

使用 String.split() 将带有引号的 csv 文件拆分为文本分隔符

将固定长度的逐行文本文件转换为 SQL 并转置

将文本对拆分为单独的列