Использование LIKE в предложении Oracle IN

Я знаю, что могу написать запрос, который будет возвращать все строки, содержащие любое количество значений в данном столбце, например:

Select * from tbl where my_col in (val1, val2, val3,... valn)

но если val1, например, может появиться где угодно в my_col, который имеет тип данных varchar (300), я мог бы написать:

select * from tbl where my_col LIKE '%val1%'

Есть ли способ расчесывать эти два метода. Мне нужно найти около 30 возможных значений, которые могут появляться в любом месте текста свободной формы столбца.

Совмещение этих двух операторов следующими способами не работает:

select * from tbl where my_col LIKE ('%val1%', '%val2%', 'val3%',....) 

select * from tbl where my_col in ('%val1%', '%val2%', 'val3%',....)

Ответ 1

select * from tbl 
where my_col like '%val1%' or my_col like'%val2%' or my_col like '%val3%', ...

Но будьте осторожны, это может быть довольно медленным... В качестве альтернативы вы можете вставить все приемлемые значения (включая знаки %) в таблицу и полусоединить эту таблицу:

select * from tbl
where exists (select 1 from all_likes where tbl.my_col like all_likes.value)

Для истинного полнотекстового поиска вы можете посмотреть текст Oracle:

http://www.oracle.com/technetwork/database/enterprise-edition/index-098492.html

Ответ 2

Нет, вы не можете этого сделать. Значения в предложении IN должны быть точными совпадениями. Вы можете изменить выбор следующим образом:

SELECT *
  FROM tbl
 WHERE my_col LIKE %val1%
    OR my_col LIKE %val2%
    OR my_col LIKE %val3%
 ...

Если val1, val2, val3... достаточно похожи, вы можете использовать регулярные выражения в REGEXP_LIKE-операторе.

Ответ 3

Да, вы можете использовать этот запрос:

  SELECT * FROM RandomTable rt 
    WHERE EXISTS (select 1 from table(sys.dbms_debug_vc2coll(//INSERT STRINGS SEPARATED BY COMMA HERE)) as MemoryTable mt where rt.name like mt.column_value);

Таким образом, вам не нужно создавать таблицу.

Ответ 4

A REGEXP_LIKE выполнит поиск в регулярном выражении без учета регистра.

select * from Users where Regexp_Like (User_Name, 'karl|anders|leif','i')

Это будет выполнено как полное сканирование таблицы - так же, как решение LIKE or, поэтому производительность будет действительно плоха, если таблица не мала. Если он не используется часто вообще, это может быть нормально.

Если вам нужна какая-то производительность, вам понадобится Oracle Text (или какой-то внешний индексатор).

Чтобы получить индексирование подстроки с помощью Oracle Text, вам понадобится индекс CONTEXT. Это немного связано с тем, что он делал для индексирования больших документов и текста с использованием большого количества смартфонов. Если у вас есть особые потребности, такие как поиск подстроки в цифрах и все слова (включая "a", "a", пробелы и т.д.), Вам нужно создать пользовательские лексеры для удаления некоторых умных материалов...

Если вы вставляете много данных, Oracle Text не будет работать быстрее, особенно если вам нужно, чтобы индекс обновлялся внутри транзакций, а не периодически.

Ответ 5

select * from tbl
 where exists (select 1 from all_likes where all_likes.value = substr(tbl.my_col,0, length(tbl.my_col)))