0

形式のデータがあります

データ

column1 column2
abcd    ~123~abd~

列 2 のデータは ~ で区切られています

出力は 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 に答える