2011-06-22 10 views
1

Oracle 11gの正規表現を使用して、列からテキストを抽出したいとします。私は仕事をする2つのクエリがありますが、私はそれを行う(クリーナー/より良い)方法を探しています。クエリーを1つのクエリーまたは新しい同等のクエリーに結合することがあります。ここで彼らは、次のとおりOracle 11gの表からパターンを抽出するにはどうすればよいですか?

クエリ1:

select column1 from table1 where regexp_like(column1, pattern); 

クエリ2:一致する行からのすべてのマッチしたテキストを抽出するパターンに一致する行を識別する。

select regexp_substr(matching_row, pattern, 1, level) 
from dual 
connect by level < regexp_count(matching_row, pattern); 

私はPL/SQLを使用してこれらの2つのクエリを結合しますが、それは面倒で不器用です。 1つのクエリにどのように組み合わせることができますか。ありがとうございました。

UPDATE:パターン 'BC' のサンプルデータ:

row 1: ABCD 
row 2: BCFBC 
row 3: HIJ 
row 4: GBC 

期待される結果は 'BC' の4行のテーブルです。

+0

興味深い...データの見た目と希望の結果のサンプルを投稿できますか? – FrustratedWithFormsDesigner

+0

+1 - 面白いエクササイズ! – DCookie

答えて

1

あなたも必要ありません1クエリ、ファンクション/手順/パッケージでそれを行うことができます。

WITH t1 AS (
SELECT 'ABCD' c1 FROM dual 
UNION 
SELECT 'BCFBC' FROM dual 
UNION 
SELECT 'HIJ' FROM dual 
UNION 
SELECT 'GBC' FROM dual 
) 
SELECT c1, regexp_substr(c1, 'BC', 1, d.l, 'i') thePattern, d.l occurrence 
    FROM t1 CROSS JOIN (SELECT LEVEL l FROM dual CONNECT BY LEVEL < 200) d 
WHERE regexp_like(c1,'BC','i') 
    AND d.l <= regexp_count(c1,'BC'); 

C1 THEPATTERN   OCCURRENCE 
----- -------------------- ---------- 
ABCD BC       1 
BCFBC BC       1 
BCFBC BC       2 
GBC BC       1 

SQL> 

私はメーリングリストへ、200での検索に出現回数を任意に制限されてきました。

0

実際には、追加のマイルを走らせたくない場合は、1つのクエリでこれを行うためのエレガントな方法があります。これは単なるスケッチであることに注意してください、私はそれを実行していない、あなたはおそらくそれにいくつかの誤植を修正する必要があります。

create or replace package yo_package is 
    type word_t is record (word varchar2(4000)); 
    type words_t is table of word_t; 
end; 
/

create or replace package body yo_package is 

    function table_function(in_cur in sys_refcursor, pattern in varchar2) 
    return words_t 
    pipelined parallel_enable (partition in_cur by any) 
    is 
    next varchar2(4000); 
    match varchar2(4000); 
    word_rec word_t; 
    begin 
    word_rec.word = null; 

    loop 

    fetch in_cur into next; 
    exit when in_cur%notfound; 

    --this you inner loop where you loop through the matches within next 
    --you have to implement this 
    loop 
     --TODO get the next match from next  
     word_rec.word := match; 
     pipe row (word_rec);  
    end loop; 

    end loop; 

    end table_function; 

end; 
/


select * 
from table(
    yo_package.table_function(
     cursor(
      --this is your first select 
      select column1 from table1 where regexp_like(column1, pattern) 
     ) 
    ) 
+1

http://static.images.memegenerator.net/Instances400/8/8201/8398245.jpg – bpgergo

関連する問題