跨多行拆分可变长度分隔字符串(SQL)

Posted

技术标签:

【中文标题】跨多行拆分可变长度分隔字符串(SQL)【英文标题】:Splitting variable length delimited string across multiple rows (SQL) 【发布时间】:2010-08-11 09:40:08 【问题描述】:

我有一个表,其中一列中包含一个可变长度的分隔字符串,例如:

20,0, 5,,^24,0, 0,,^26,0, 0,,^ 281,0, 0,,^34,0, 2,,^48,0, 2,,^44,0, 2,,^20,0, 10,,^ 20,5, 5,,^379,1, 1,,^26,1, 2,,^32,0, 1,,^71,0, 2,,^

我需要做的是拆分这个字符串,以便 ^ 字符之后的每个数字都返回一个新行。喜欢:

货品编号 货品代码 项目 1 20 项目 2 ^24 项目 3 ^24 项目 4 ^27 项目 5 ^28 项目 6 ^65 项目 7 ^66 项目 8 ^39 项目 9 ^379 项目 10 ^448 项目 11 ^427

我尝试了各种拆分函数,我可以通过对多列中的值进行子串化,然后使用 unpivot 在多行中返回它们来实现我需要的结果,但是这种方法不能处理这个字符串的可变长度.

有更好的方法的想法吗?

【问题讨论】:

Oracle 具有用于此目的的管道功能。 SQL Server 中可能有类似的东西。 管道函数需要生成的行数作为输入变量传递,不是吗?我不知道将为每个输入行生成的行数 【参考方案1】:

首先,我只想说,这就是您首先不应该在字段中使用逗号分隔数据的原因。没有简单或有效的方法来使用它。

也就是说,您可以使用递归查询来拆分字符串并从中获取数字:

with split as
(
  select
    item = cast('' as varchar(max)),
    source = cast('20,0, 5,,^24,0, 0,,^26,0, 0,,^281,0, 0,,^34,0, 2,,^48,0, 2,,^44,0, 2,,^20,0, 10,,^20,5, 5,,^379,1, 1,,^26,1, 2,,^32,0, 1,,^71,0, 2,,^' as varchar(max))
  union all
  select
    item = substring(source, 1, charindex(',,', source)),
    source = substring(source, charindex(',,', source) + 2, 10000)
  from split
  where source > ''
)
select substring(item, 1, charindex(',', item) -1)
from split
where item > ''

结果:

20
^24
^26
^281
^34
^48
^44
^20
^20
^379
^26
^32
^71

【讨论】:

我没有机会回到办公室进行测试,但如果源是数据库中的列,这是否可行。例如在第 5 行中使用 source = cast((select [Column] from [dbo].[Table]) as varchar(max)) ?? @Matt:是的,只要它是一个字符串。否则,您必须将其放入表值函数中,并从查询中调用该函数。

以上是关于跨多行拆分可变长度分隔字符串(SQL)的主要内容,如果未能解决你的问题,请参考以下文章

如何根据一个字段是不是包含oracle sql中的逗号分隔字符串将单行拆分为多行?

关于在Hive中将特定字符分隔的字符串拆分成多行的应用

在批处理文件中拆分以逗号分隔的字符串并在循环中调用 sqlplus 函数

SQL 将值拆分为多行

一句话实现字段拆分成多行

如何使用横向视图将分隔字符串拆分为 Hive 中的多行