0

我有格式的数据

数据

column1 column2
abcd    ~123~abd~

第 2 列中的数据由 ~ 分隔

输出应采用两行格式

column1 column2
abcd    123
abcd    abd

可以请一些帮助。

4

2 回答 2

0

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() 调用是删除前导和尾随实例所必需的~(尽管也许标记器函数可以处理它。嗯......)

于 2013-01-09T13:54:48.120 回答
0

样本数据为

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
于 2013-01-09T13:55:00.673 回答