将表中字符串列的单词与另一列oracle中的字符串单词匹配

Posted

技术标签:

【中文标题】将表中字符串列的单词与另一列oracle中的字符串单词匹配【英文标题】:Match words of string column in a table with words of string in another column oracle 【发布时间】:2013-11-04 14:06:59 【问题描述】:

我有两个表,例如两个小输入表:-

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 

P.S:- 我只提供了一种情况的输出,表格会很大。也无法在列数据之间添加空格,所以使用引号。

我已经尝试过使用层次查询来打破字符串,但这需要很多时间:- 我如何打破字符串的示例:-

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;

有人能推荐一个好的方法吗--

【问题讨论】:

您是否只希望 table2.columnB 中的值完全包含在 table1.columnA 中? 不,抱歉没有给出正确的例子。我想为表 B 获取该列,该列在 A 列中的一行具有最大匹配词数。也编辑我的帖子 是否要惩罚 table2 中不包含在 table1 中的单词? IE。如果匹配“生活美好”,“生活美好但太短”的得分应该低于“生活美好”吗? (根据您的示例,两者都会得到 number_of_words = 3) @FrankSchmitt :- 由于我在 table1 中没有任何带有 'life' 或 ' is' 或 'good' 的字符串,因此不需要返回它。我想要 table1 中的字符串和表 2 中最匹配的字符串。通过大多数匹配,我的意思是 table1 的字符串和 table2 的字符串之间匹配的单词数应该是最高的 @eric.itzhak :- Soundex 不是我需要的,因为它只是根据“听起来像”来分配价值 【参考方案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;

【讨论】:

以上是关于将表中字符串列的单词与另一列oracle中的字符串单词匹配的主要内容,如果未能解决你的问题,请参考以下文章

将表中的一列替换为不同表中的列并选择 *

返回查询的所有行,其中一列中的字符串值与另一列中的字符串值匹配

返回值的公式,其中一列中的第一个单词与另一列的最后四位匹配

Oracle:比较两个不同表中没有主键的字符串列以查找匹配/不匹配的字符串

如何在条件与数字之间使用 Oracle 中的字符串列

oracle怎么将表中字段的很长的字符串数据更改其中一两个字符