我有格式的数据
数据
column1 column2
abcd ~123~abd~
第 2 列中的数据由 ~ 分隔
输出应采用两行格式
column1 column2
abcd 123
abcd abd
可以请一些帮助。
我有格式的数据
数据
column1 column2
abcd ~123~abd~
第 2 列中的数据由 ~ 分隔
输出应采用两行格式
column1 column2
abcd 123
abcd abd
可以请一些帮助。
Oracle 没有内置的字符串分词器,但构建我们自己的很容易。有几种不同的解决方案(在 SO 和更广泛的互联网上),但我将使用一个函数,string_tokenizer()
我在另一个答案中发布了一些。
with data as ( select column1
, trim(both '~' from column2) as column2
from your_table )
select data.column1
, t.column_value
from data
, table ( string_tokenizer (data.column2, '~'))t;
顺便说一下,TRIM() 调用是删除前导和尾随实例所必需的~
(尽管也许标记器函数可以处理它。嗯......)
样本数据为
SQL> select * from your_table;
COLUMN1 COLUMN2
-------------------- --------------------
abcd ~123~abd~
foo ~test~test2~
foo2 ~test~
示范条款(10g+):
SQL> with foo as (select rownum id, column1, column2, length(regexp_replace(column2, '[^~]', ''))-1 elem_cnt
2 from your_table)
3 select column1, elem
4 from (select column1, elem, f
5 from foo
6 model partition by(id)
7 dimension by(0 as f)
8 measures(column1, column2, elem_cnt,
9 cast('' as varchar2(4000)) elem)
10 rules (elem [for f from 0 to elem_cnt[0]-1 increment 1]
11 = substr(column2[0], instr(column2[0], '~', 1, cv(f)+1) + 1,
12 instr(column2[0], '~', 1, cv(f)+2) - instr(column2[0], '~', 1, cv(f)+1) - 1),
13 column1[any] = column1[0]))
14 order by f;
COLUMN1 ELEM
-------------------- --------------------
abcd 123
abcd abd
foo test
foo test2
foo2 test
或 11g 递归子查询分解:
SQL> with data (id, column1, column2, elem, elem_cnt, curr_elem)
2 as (select rownum id, column1, column2,
3 substr(column2, instr(column2, '~') + 1,
4 instr(column2, '~', 1, 2) - instr(column2, '~') - 1) elem,
5 length(regexp_replace(column2, '[^~]', ''))-1 elem_cnt,
6 1 as curr_elem
7 from your_table
8 union all
9 select rownum id, column1, column2,
10 substr(column2, instr(column2, '~', 1, elem_cnt) + 1,
11 instr(column2, '~', 1, elem_cnt+1) - instr(column2, '~', 1, elem_cnt) - 1) elem,
12 length(regexp_replace(column2, '[^~]', ''))-1 elem_cnt,
13 curr_elem + 1
14 from data
15 where curr_elem < elem_cnt)
16 select column1, elem
17 from data
18 order by column1, curr_elem;
COLUMN1 ELEM
-------------------- --------------------
abcd 123
abcd abd
foo test
foo test2
foo2 test