Лучший способ оператора SQL 'LIKE' с большим количеством предложений

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

SELECT fieldname 
FROM table 
WHERE textfield LIKE '%val1%' 
  OR  textfield LIKE '%val2%' 
  OR  textfield LIKE '%val3%' 
  .
  .
  OR  textfield LIKE '%valn%'

Мой вопрос: насколько это эффективно, когда количество предложений LIKE приближается к сотне. Есть ли лучший способ сделать это?

Использование ORACLE 11g

Я пытался объединить «%val1%» .. «%valn%» в шаблон регулярного выражения, но он стал только более сложным и нечитаемым.

🤔 А знаете ли вы, что...
SQL позволяет создавать ограничения целостности данных, такие как уникальность и внешние ключи.


52
2

Ответы:

Если вы сохраняете искомые значения в столбце val столбца separate_table, вы можете упростить запрос до

SELECT a.fieldname 
FROM table a join separate_table s on a.textfield like '%' || s.val || '%'

Эффективность? Ничто не является очень эффективным при таком поиске. Возможно, вы могли бы взглянуть на Oracle Text и посмотреть, какой тип поиска он предлагает.


Решено

Если вы ищете слова в каком-то тексте, вы можете использовать Oracle Text для индексации текста и CONTAINS для его фильтрации.

Учитывая примерные данные:

CREATE TABLE table_name ( fieldname, textfield ) AS
SELECT 1, 'This is some text that does not contain your values.' FROM DUAL UNION ALL
SELECT 2, 'This is some text where val1 is contained.' FROM DUAL UNION ALL
SELECT 3, 'This has val2 and val3.' FROM DUAL UNION ALL
SELECT 4, 'This is some text that does not contain your values.' FROM DUAL UNION ALL
SELECT 5, 'This has upper-case VAL1.' FROM DUAL UNION ALL
SELECT 6, 'This has mixed-case VaLn.' FROM DUAL UNION ALL
SELECT 7, 'This has val100.' FROM DUAL;

Затем вы можете создать индекс Oracle Text:

CREATE INDEX table_name__textfield__textidx
  ON table_name(textfield) INDEXTYPE IS CTXSYS.CONTEXT;

и используйте запрос:

SELECT fieldname, textfield
FROM   table_name
WHERE  CONTAINS(textfield, 'val1 OR val2 OR val3 OR valn', 1) > 0

Какие выходы:

ИМЯ ПОЛЯ ТЕКСТОВОЕ ПОЛЕ 2 Это текст, в котором содержится значение val1. 3 Здесь есть val2 и val3. 5 Это значение VAL1 в верхнем регистре. 6 Это VaLn в смешанном случае.

Строка, содержащая val100, не соответствует val1, поскольку это разные слова. Если вы хотите сопоставить основу слов, используйте % в фильтре «Содержит»:

SELECT fieldname, textfield
FROM   table_name
WHERE  CONTAINS(textfield, 'val1% OR val2% OR val3% OR valn%', 1) > 0

Какие выходы:

ИМЯ ПОЛЯ ТЕКСТОВОЕ ПОЛЕ 2 Это текст, в котором содержится значение val1. 3 Здесь есть val2 и val3. 5 Это значение VAL1 в верхнем регистре. 6 Это VaLn в смешанном случае. 7 Это имеет значение val100.

рабочий пример