使用oracle按分隔符位置拆分字符串
Posted
技术标签:
【中文标题】使用oracle按分隔符位置拆分字符串【英文标题】:Split String by delimiter position using oracle 【发布时间】:2017-01-30 16:20:04 【问题描述】:我在 oracle 表中有一个类似 ',,defoifcd,87765' 的字符串。意思是,前两个字符串是空的。所以我需要在 Oracle 中用逗号分隔字符串作为分隔符。我正在编写这个查询
SELECT
REGEXP_SUBSTR (TEST_STRING, '[^,]+', 1, 1) AS part_1,
REGEXP_SUBSTR (TEST_STRING, '[^,]+', 1, 2) AS part_2,
REGEXP_SUBSTR (TEST_STRING, '[^,]+', 1, 3) AS part_3,
REGEXP_SUBSTR (TEST_STRING, '[^,]+', 1, 4) AS part_4
FROM ABCD
;
这里 ABCD 是我的表,TEST_STRING 是我的库。
但结果返回像
PART_1, part_2, part_3, part_4
defoifcd,87765
但我想要这样的结果,
PART_1, part_2, part_3, part_4
defoifcd, 87765
意味着我需要 part_3 和 part_4 列中的 'defoifcd' 和 '87765' 值,因为前两个字符串是空的,但根据我的查询,它在 part_1 和 part_2 列中是 comimg。
【问题讨论】:
Split comma separated values to columns in Oracle的可能重复 非常具体:不要检查接受的答案,而是检查 Gary 的答案:他正在解释和解决您当前的问题。 总是正好是四个部分吗? 并不总是四部分。 那么您将无法像这样排列列。除非您使用“动态 SQL”(这是一个不同的过程,并且通常不是最佳的),否则在查看数据之前必须提前知道输出列的数量。是否有预先已知的可用于查询的最大零件数?如果不是,您真的需要按列输出(而不是一列用于指定部件,另一列用于值)? 【参考方案1】:如果你只有一个字符串并且你知道它总是正好有四个部分,你可以像这样拆分它,只使用标准的字符串函数(并避免使用更灵活但通常更慢的正则表达式)。
注意:此答案的后半部分涉及“部分”数量可变的字符串。
with inputs ( str ) as (
select ',,defoifcd,87765' from dual
)
-- end of TEST data; SQL query begins below (use your actual table and column names)
select substr(str, 1, instr(str, ',') - 1) as part_1,
substr(str, instr(str, ',') + 1,
instr(str, ',', 1, 2) - instr(str, ',') - 1) as part_2,
substr(str, instr(str, ',', 1, 2) + 1,
instr(str, ',', 1, 3) - instr(str, ',', 1, 2) - 1) as part_3,
substr(str, instr(str, ',', -1) + 1) as part_4
from inputs;
PART_1 PART_2 PART_3 PART_4
-------- -------- -------- --------
defoifcd 87765
1 row selected.
如果事先不知道零件的数量,最好以不同的格式获得输出(参见下面的输出)。如果需要在所有其他处理完成后将部分排列在列中 - 最好留给报告应用程序,而不是在 SQL 中完成。
with inputs ( id, str ) as (
select 1, ',,defoifcd,87765' from dual union all
select 2, '' from dual union all
select 3, 'a, b, c' from dual
)
-- end of TEST data; SQL query begins below (use your actual table and column names)
select id, str, level as part_number,
substr(aug_str, instr(aug_str, ',', 1, level) + 1,
instr(aug_str, ',', 1, level + 1) - instr(aug_str, ',', 1, level) - 1) as val
from ( select id, str, ',' || str || ',' as aug_str from inputs)
connect by level <= length(str) - length(translate(str, 'z,', 'z')) + 1
and prior id = id
and prior sys_guid() is not null
;
ID STR PART_NUMBER VAL
-- ---------------- ----------- ----------
1 ,,defoifcd,87765 1
1 ,,defoifcd,87765 2
1 ,,defoifcd,87765 3 defoifcd
1 ,,defoifcd,87765 4 87765
2 1
3 a, b, c 1 a
3 a, b, c 2 b
3 a, b, c 3 c
8 rows selected.
【讨论】:
你的第一个例子正是我正在经历的;你的第二个例子很有创意;)以上是关于使用oracle按分隔符位置拆分字符串的主要内容,如果未能解决你的问题,请参考以下文章
使用 regexp_substr 在 Oracle 中按空格和字符拆分字符串作为分隔符