基于SQL Server中的分隔符将文本拆分为多列
Posted
技术标签:
【中文标题】基于SQL Server中的分隔符将文本拆分为多列【英文标题】:Splitting text to multiple columns based on delimiter in SQL server 【发布时间】:2021-01-11 12:08:54 【问题描述】:我正在尝试将数据从暂存表加载到 SQL Server 中的最终表。我的列分隔符是管道字符“|”。但我在文本列中得到管道字符,如下所示。
我在stage表中的数据如下图:
1233|"abcd,edfg"|asdf|3456
1234|xyz|"abnd|tfgt"|8765
我正在尝试编写一个标量函数,它基于管道作为分隔符将阶段表的内容拆分为多个列。
期望的输出应该是:
col_1 | col_2 | col_3 | col_4 |
---|---|---|---|
1233 | "abcd|edfg" |
asdf | 3456 |
1234 | xyz | "abnd|tfgt" |
8765 |
如果我尝试在 SQL Server 中使用 substring 和 charindex 函数将其拆分,我最终会通过导致列移位问题将“abcd”和 edfg 拆分为 2 个单独的列。
实现这一目标的最佳方法是什么?
【问题讨论】:
一开始就不要存储这样的值。这是一个极其严重的设计错误,它甚至打破了最基本的设计规则。一个单元格应包含一个原子值 在将数据存储到数据库之前 拆分和清理数据要容易得多。例如,编写一个 Python 或 C# 脚本来拆分多值输入并将每个值存储在另一个表的单独行中会更容易。如果数据已经存储在生产环境中,您可以使用STRING_SPLIT
并将额外的值存储在不同的表中
这是我的临时表的设计。它只是临时加载数据,发布我们进行列拆分并加载到最终表中。决赛桌采用适当的列格式设计。
在将数据加载到临时表之前拆分数据。这个是从哪里来的?双引号真的存在吗?可能有办法完全避免这种情况。例如,如果您从文本文件加载数据,您可以指定|
作为字段分隔符。 "abnd|tfgt"
比较棘手,因为这表示 CSV 包含一个包含 abnd|tfgt
的 single 字符串。 SQL 尤其是 T-SQL 在字符串操作方面很糟糕。如果您必须解析自定义格式,使用另一种语言会容易得多
假设有人有创建多值“CSV”格式的好主意。在 C# 中编写一个简单的解析器比尝试在 SQL 中处理它要容易得多。在 C# 中,您可以使用 ReadLine
一次加载一行,String.Split
拆分单元格,然后另一个 String.Split
拆分“多值”字段。
【参考方案1】:
如果你知道总是有两个值,只需使用字符串函数:
select s.*,
left(col_2, charindex('|', col_2 + '|') - 1) as col_2_left,
stuff(col_2, 1, charindex('|', col_2 + '|'), '') as col_2_right
from staging s;
您需要对可能有重复的每一列重复此操作。
Here 是一个 dbfiddle。
【讨论】:
以上是关于基于SQL Server中的分隔符将文本拆分为多列的主要内容,如果未能解决你的问题,请参考以下文章
Pandas使用split函数基于指定分隔符拆分数据列的内容为列表设置expand参数将拆分结果列表内容转化为多列数据并添加到原数据中replace函数基于正则表达式替换字符串数据列中的匹配内容
Pandas使用split函数基于指定分隔符拆分数据列的内容为列表设置expand参数将拆分结果列表内容转化为多列dataframe并添加到原dataframe中drop函数基于数据列名称删除列
Pandas使用split函数基于指定分隔符拆分数据列的内容为列表设置参数n控制拆分的次数设置expand参数将拆分结果列表内容转化为多列dataframe并添加到原dataframe中