【问题标题】:Substitutions in like statement in OracleOracle中like语句中的替换
【发布时间】:2019-11-22 05:21:42
【问题描述】:

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

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

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

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

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

谢谢

【问题讨论】:

    标签: sql database oracle query-optimization sql-like


    【解决方案1】:

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

    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])', 
              '\1' || i.word || '\2', 1, 0,  'i');
        end loop;
    
       return p_text;
    end;
    

    【讨论】:

    • 感谢@Ponder Stibbons,这是一个很好的解决方案。只是一个问题,当这个词出现在两个类别中时怎么样?白天一直在想,但一直没能想出一个主意,根据一个词所在的类别数来获取几条记录。更具体的例子,请看这个fiddle: dbfiddle.uk/…
    • 当一个词匹配多个类别时,我尝试将可能的值存储在一个数组中,但我得到了`ORA-06532:下标超出限制,但我增加了数组的大小。请检查这个最新版本,尝试有一个工作版本来处理多个类别中匹配的单词:dbfiddle.uk/…
    • 似乎我将 dbfiddle 作为 PL/SQL 块工作,但在将其转换为函数时出现错误。我收到错误消息:ORA-06502: PL/SQL: numeric or value error: character to number conversion error 第 37 行:array(1):= p_text;。在 PL/SQL 块中,我得到了正确的记录,但现在我得到了那个错误。你知道我该如何解决吗?你认为我过去在同义词列表中找到一个在不同类别中具有多个匹配项的单词是一种好方法吗?非常感谢
    • 关于此错误,我尝试在简化示例中复制它,但一无所获。您必须调试值并查看转换的内容。但我不会存储与WORDSYN_LIST 的一部分相同的值。这是无限循环的直接方法。
    • 当我有几个同义词的单词时,你认为存储在一个数组中吗?
    【解决方案2】:

    你能确认我的理解吗 搜索字符串“FORMULA VU SCHOOL”的第一部分是“FORMULA”,如果有以“FORMULA”开头的字符串,则需要在表机构中进行检查。 在这种情况下,点击“FORMULA VIEW UNIVERSITY”

    然后取出字符串的第二部分(“VIEW”)并在表格 subs 中查找它。

    然后取出字符串的第三部分(“UNIVERSITY”)并查找表 syns

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

    公式视图大学 = 公式视图教育

    由于我们正在搜索“FORMULA VU SCHOOL”是否已经存在,当以上述方式进行翻译时,我们会得到

    FORMULA VU SCHOOL = FORMULA VIEW 教育

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

    Existing_column_value   search_string_value
    FORMULA VIEW UNIVERSITY FORMULA VU SCHOOL
    

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

    【讨论】:

    • 有点不同。为了更清楚,让我们稍微改变一下这个例子。假设我们有4MULA VU SCHOOL。每个单词都需要检查单词替换和同义词。比如第一个字4MULA,只要换字就换成FORMULA,然后第二个字VU,也只有换字,换成VIEW。最后一个词SCHOOL 通过单词替换检查,但它没有,然后我们检查同义词列表,发现“SCHOOL”与“UNIVERSITY”在同一个列表中。结果,4MULA VU SCHOOL 被认为与FORMULA VIEW UNIVERSITY 相同
    猜你喜欢
    • 2015-03-10
    • 1970-01-01
    • 1970-01-01
    • 2021-05-04
    • 1970-01-01
    • 2011-10-18
    • 2013-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多