Oracle 中 like 语句中的替换

Substitutions in like statement in Oracle

我有一个名为 syns 的 synonyms table 来存储单词和现有的同义词。以同样的方式,还有另一个名为 subs 的 table,它包含一个单词的 word substitutions。这些 table 用于在名为 institutions 的主 table 中查找相似值,该主 institutions 托管数据库中的现有名称。

这样做的目的是为了避免考虑同义词和单词替换的相似名称。用户提供了一个新的机构名称,并且在插入机构 table 之前,有几个查询将每个单词替换为其同义词和单词替换。例如,我有以下数据:

substitution word table:
WORD      SUBS_LIST
MOUNTAIN  MOUNTAIN, MOUNT, MT, MTN
VIEW      VIEW, VU
FORMULA   FORMULA, 4MULA
Synonym list table:
WORD    SYN_LIST
EDUCATION   SCHOOL, UNIVERSITY, COLLEGE, TRAINING
institutions table:
NAME
FORMULA VIEW UNIVERSITY
FOURMULAE VULCAN COLLEGE
4MULA VU CAFE

机构 table 包含数据库中的所有现有名称。然后,当收到一个新名称时,在用其各自的同义词列表和单词替换替换每个单词时,这不必是相似的。例如,由于存在记录 FORMULA VIEW UNIVERSITY.

,因此应该在数据库中找到一个新名称,例如 FORMULA VU SCHOOL

我创建了 this fiddle 来展示这个想法。但是,我没有得到任何结果。

谢谢

你能证实我的理解吗 搜索字符串"FORMULA VU SCHOOL"的第一部分是"FORMULA",如果有以"FORMULA"开头的字符串,则需要在table机构中进行检查。 在这种情况下,命中 "FORMULA VIEW UNIVERSITY"

然后获取字符串的第二部分 ("VIEW") 并查找 table 子项。

然后取字符串的第三部分("UNIVERSITY")并在table syns

中查找

之后在table机构中找到的字符串将被翻译为

FORMULA VIEW 大学 = FORMULA VIEW 教育

因为我们正在搜索 "FORMULA VU SCHOOL" 是否已经存在,当以上述方式翻译时我们会得到

FORMULA VU 学校 = FORMULA VIEW 教育

并且由于 table 机构中已经存在这样的翻译记录,因此该记录需要在预期输出中显示如下

Existing_column_value   search_string_value
FORMULA VIEW UNIVERSITY FORMULA VU SCHOOL

你能确认这是否是你要找的吗?

以下功能似乎有效。它使用一种将逗号分隔的字符串拆分为单词的技术,您可以应用其他的。但最好的办法是将数据模型更改为单个单词同义词,这样就可以避免拆分,这可能不可靠。您可以在检查新条目时使用此功能,例如:

where replace_synonyms(inserted_value) <> replace_synonyms(existing_value)

dbfiddle

测试:

select replace_synonyms('FORMULA VIEW UNIVERSITY') from dual;  
-- FORMULA VIEW EDUCATION
select replace_synonyms('CANTINA TRAINING MT')     from dual;  
-- FOOD EDUCATION MOUNTAIN

函数:

create or replace function replace_synonyms(i_text in varchar2) return varchar2
is
    p_text varchar2(4000) := i_text;

    cursor c_subs is
    select word, trim(column_value) text 
      from subs, xmltable(('"' ||replace(subs_list, ',', '","') || '"'))
      where p_text like '%'||trim(column_value)||'%'
    union 
    select word, trim(column_value) text 
      from syns, xmltable(('"' ||replace(syn_list, ',', '","') || '"'))
      where p_text like '%'||trim(column_value)||'%';

begin
   for i in c_subs
    loop
      p_text := regexp_replace(
          p_text, '(^|[^a-z0-9])' || i.text || '($|[^a-z0-9])', 
          '' || i.word || '', 1, 0,  'i');
    end loop;

   return p_text;
end;