【问题标题】:Oracle check if a string in column in table a contains word from column in table bOracle检查表a列中的字符串是否包含表b列中的单词
【发布时间】:2019-11-02 00:43:26
【问题描述】:

在 Oracle 11.2.0.4... 给定表 A 有一个长的 varchar 列,其中包含文本段落,我想检查该文本中的任何单词是否存在于具有单数单词垂直列表的表中。 我正在寻找一种在单个查询中执行此操作的方法,而不是使用游标。

基本上,我认为我需要将段落分成单词,然后加入垂直单词表,但不知道如何进行。

Example:
TableA:

+----+--------------------------------------------+
| id |                  comments                  |
+----+--------------------------------------------+
|  1 | This sentence has no reference to any word |
|  2 | But this one references jungle             |
|  3 | And this one references Trees              |
+----+--------------------------------------------+

TableB:

+----+---------+
| id |  word   |
+----+---------+
|  1 | Jungle  |
|  2 | Forest  |
|  3 | Trees   |
|  4 | Animals |
|  5 | River   |
+----+---------+

鉴于这些表,我想要一个 SQL 查询,它会告诉我表 A 的第 2 行和第 3 行包含表 B 中存在的单词。

我研究过使用 xmltype 功能将表格拆分为单词,然后像这样将它们连接在一起:

select id, 
(select count(1) from tableb f, xmltable(
  '/r/c/text()'
  passing xmltype('<r><c>'||replace((regexp_replace(comments, '[^a-z][^A-Z]')), ' ', '</c><c>')||'</c></r>')
  columns subs varchar2(4000) path '.'
) s where trim(f.word) = trim(s.subs)) words_found, comments
from tablea
where trim(comments) is not null

但这不是很好。它在失败之前只能处理一小部分注释行。

提前致谢,如果已得到解答,我深表歉意。我做了很多检查,但没有找到我要找的东西。

【问题讨论】:

    标签: sql oracle oracle11g


    【解决方案1】:

    由于您只是比较单词,因此不需要拆分它们。您可以在JOIN 中使用LIKE 表达式

    select a.*, b.* from TableA a  JOIN TableB b  ON 
    ' ' ||lower(a.comments)|| ' ' like  '% '||lower(b.word)||' %'
    

    REGEXP_LIKE

    select a.*, b.* from TableA a  JOIN TableB b  ON 
    REGEXP_LIKE(a.comments,'(^|\W)'||b.word||'($|\W)','i');
    

    Demo

    【讨论】:

    • 哇,这么简单的答案。我把事情复杂化了。太棒了,谢谢!
    【解决方案2】:

    简单的INSTR怎么样?

    SQL> with
      2  a (id, comments) as
      3    (select 1, 'This sentence has no reference to any word' from dual union all
      4     select 2, 'But this one references jungle'             from dual union all
      5     select 3, 'And this one references Trees'              from dual union all
      6     select 4, 'Jungle animals swim in a river'             from dual
      7    ),
      8  b (id, word) as
      9    (select 1, 'Jungle' from dual union all
     10     select 2, 'Forest' from dual union all
     11     select 3, 'Trees'  from dual union all
     12     select 4, 'Animals' from dual union all
     13     select 5, 'River'   from dual
     14    )
     15  select a.id, a.comments, b.word
     16  from a cross join b
     17  where instr(lower(a.comments), lower(b.word)) > 0
     18  order by a.id, b.word;
    
            ID COMMENTS                                   WORD
    ---------- ------------------------------------------ -------
             2 But this one references jungle             Jungle
             3 And this one references Trees              Trees
             4 Jungle animals swim in a river             Animals
             4 Jungle animals swim in a river             Jungle
             4 Jungle animals swim in a river             River
    
    SQL>
    

    【讨论】:

    • 这也将匹配 Riverdale 和 Jungle.com
    • 不应该吗?
    • 对不起,我不清楚。我不是在寻找部分命中。否则它会满足我的要求。
    • 没问题,@Jeff。很高兴您在 Kaushik 的帮助下解决了问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-04
    • 2017-10-16
    • 1970-01-01
    • 2021-10-10
    • 2020-02-26
    相关资源
    最近更新 更多