Oracle проверяет, содержит ли строка в столбце таблицы a слово из столбца таблицы b - PullRequest
0 голосов
/ 20 февраля 2019

В 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-запрос, который сказал бы мне, что строки 2 и 3 таблицы A содержат слова, которые существуют в таблице 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

, но это не очень хорошо работает.Он может обработать только небольшой набор строк комментариев до сбоя.

Заранее спасибо, и я прошу прощения, если на этот вопрос был дан ответ.Я довольно много проверял и не нашел то, что искал.

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

Как насчет простого 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>
0 голосов
/ 21 февраля 2019

Поскольку вы сравниваете только слова, разделять их не обязательно.Вы можете использовать выражение LIKE в JOIN

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');

Демо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...