2

たとえば、2 つの小さな入力テーブルを使用する 2 つのテーブルがあります。

Table1:-

columnA   
man got wounded by dog  
joe met sally  



Table2:-  
ColumnB  
life is good  
dog man got hunt   
dumb man wounded iron   

columnA の行、columnB の行を検索したいのですが、例:-

Intermediate Output of above table should be:-
ColumnA    ColumnB    words_matching  number_of_words 
"man got wounded by dog"   "dumb man wounded iron"    "man,wounded"  2  
"man got wounded by dog"    "dog man got hunt"    "dog,man,got"   3  

最終結果の出力で、私は表示したい:-

ColumnA    ColumnB    words_matching  number_of_words 
"man got wounded by dog"    "dog man got hunt"    "dog,man,got"   3 

PS:- 1 つのケースのみの出力を提供しました。テーブルは巨大になります。また、列データ間にスペースを追加できなかったため、引用符を使用しました。

上記の階層クエリを使用して文字列を分割しようとしましたが、多くの時間がかかります:- 文字列を分割する方法の例:-

select column1,regexp_substr(column1,'[^ ]+', 1, level) break_1 from table1
 connect by regexp_substr(column1,'[^ ]+', 1, level) is not null;

以下は私が思いついた別のクエリですが、デカルト結合のためにパフォーマンスが非常に低いため、巨大なデータには良い考えではないと思います:

 select st1,st2,
 max(round((extractvalue(dbms_xmlgen.getxmltype('select cardinality (
  sys.dbms_debug_vc2coll(''' || replace(replace(lower(st1),''''), ' ', ''',''' ) || ''') multiset intersect
  sys.dbms_debug_vc2coll('''||replace(replace(lower(st2),''''), ' ', ''',''' )||'''))  x from dual'), '//text()')),2))  seq
  from (
  select l1.column1 st1,l2.column2 st2
  from
  table1 l1,table2 l2 ) group by st1,st2;

誰かが良いアプローチを提案できますか--

4

1 に答える 1

1

上記の問題に対するより高速な解決策を見つけました。手順を使用して文字列を分割し、別のテーブルに格納してから、それらのテーブルを使用して一致する文字列を見つけます。

手順:-

create or replace
procedure split_string_word_match 
as 
type varr is table of  varchar(4000);
list1 varr;
list2 varr;

begin
select distinct column1 bulk collect into list1 from table1 ;
select distinct column2 bulk collect into list2 from table2 ;

for k in list1.first..list1.last
loop
insert into list1_result
select list1(k),regexp_substr(list1(k),'[^ ]+', 1, level) break_1 from dual
 connect by regexp_substr(list1(k),'[^ ]+', 1, level) is not null;
commit;
end loop;

for i in list2.first..list2.last
loop
insert into list2_result
select list2(i),regexp_substr(list2(i),'[^ ]+', 1, level) break_2 from dual
 connect by regexp_substr(list2(i),'[^ ]+', 1, level) is not null;
commit;
end loop;
end;
/

次に、結果テーブルに対して以下のSQLを使用して、最も一致する文字列を見つけます:-(プロシージャ内の多くのループよりも高速に動作するため、SQLを記述しました)

select st1,st2,cs_string ,max(cnt) max_count
from (
select l1.column1 st1,l2.column2 st2,listagg(l1.break_1,',') within group(order by l1.break_1) cs_string ,count(1) cnt
from list1_result l1,list2_result l2
where l1.break_1 = l2.break_1
group by l1.column1,l2.column2)
group by st1,st2,cs_string;
于 2013-11-06T07:52:20.093 に答える