Мне нужно извлечь информацию из текстового поля, которое может содержать одно из многих значений. 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 позволяет создавать ограничения целостности данных, такие как уникальность и внешние ключи.
Если вы сохраняете искомые значения в столбце 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
Какие выходы:
Строка, содержащая val100
, не соответствует val1
, поскольку это разные слова. Если вы хотите сопоставить основу слов, используйте %
в фильтре «Содержит»:
SELECT fieldname, textfield
FROM table_name
WHERE CONTAINS(textfield, 'val1% OR val2% OR val3% OR valn%', 1) > 0
Какие выходы: