2017-01-30 3 views
0

Я хочу проверить, существует ли в столбце 3 конкретных слова или нет, используя запрос Oracle.Существование 3 слов в строке в запросе оракула

Например, мое значение столбца: 'Google Earth lets you fly anywhere on Earth to view satellite imagery, maps, terrain, 3D buildings, from galaxies in outer space to the canyons of the ocean'.

Я хочу проверить, существуют ли в строке три слова Earth, galaxies и buildings.

Как я могу сделать это в запросе Oracle?

+2

Вы ищете слова или строки? Учитывается ли «раскопок» или «землянин»? –

+0

только точные слова. «раскопки» не должны учитываться. – Sarath

ответ

4

Вы хотите искать слова только, вероятно. Поэтому при поиске 'space' вы не хотите найти, скажем, 'respaced'. Использовать REGEXP_LIKE с границами слов:

select * 
from mytable 
where regexp_like(text, '(^|\W)earth(\W|$)', 'i') 
    and regexp_like(text, '(^|\W)galaxies(\W|$)', 'i') 
    and regexp_like(text, '(^|\W)buildings(\W|$)', 'i'); 
+0

Для эффективности всегда лучше поставить более вероятное совпадение сначала в чередовании: '(\ W | ^)', а не наоборот (хотя в этом случае это, скорее всего, мало изменится). Другое, что это должно быть победителем. – mathguy

0

использовать что-то вроде этого в пункте где (если вы хотите, чтобы быть точным об этом случае):

where col_name like '%Earth%' 
and col_name like '%galaxies%' 
and col_name like '%buildings%' 

, как отметил @ Тим в комментариях, если вы хотите игнорировать случай, вы можете по с помощью верхней() или ниже():

where upper(col_name) like '%EARTH%' 
and upper(col_name) like '%GALAXIES%' 

т.д.

+1

Используйте 'UPPER (col_name) LIKE '% EARTH%'' для обработки возможных проблем чувствительности к регистру. –

+2

Остерегайтесь проблемы «матери в химиотерапии». Это называется так потому, что слово «мать», для которого вы, по-видимому, ищете, также встречается в слове «che ** mother ** apy». – mathguy

+0

@mathguy прав - это вернет вспомогательные слова. Я поддержал ответ Тростена. –

0

Используйте регулярное выражение:

WITH tmp AS 
    (
    SELECT 'Earth, galaxies and buildings' str FROM dual UNION ALL 
    SELECT 'Earth, buildings and galaxies' str FROM dual UNION ALL 
    SELECT 'Earth2, galaxies and buildings' str FROM dual UNION ALL 
    SELECT 'Earth , galaxies and buildings' str FROM dual UNION ALL 
    SELECT 'Earth,galaxies,buildings' str FROM dual UNION ALL 
    SELECT 'Earthgalaxiesbuildings' str FROM dual UNION ALL 
    SELECT 'earth, galaxies and buildings' str FROM dual 
) 
SELECT 
    str 
FROM 
    tmp 
WHERE 
    REGEXP_LIKE(UPPER(str), '([[:punct:][:space:]]|^)EARTH([[:punct:][:space:]]|$)') AND 
    REGEXP_LIKE(UPPER(str), '([[:punct:][:space:]]|^)GALAXIES([[:punct:][:space:]]|$)') AND 
    REGEXP_LIKE(UPPER(str), '([[:punct:][:space:]]|^)BUILDINGS([[:punct:][:space:]]|$)') 
+0

Это правильный подход. С учетом сказанного: для эффективности, в любой группе смены (например, в вашей первой группе, в поисках начала строки или для чего-то еще), лучше всего эффективно использовать наиболее частое совпадение; поместите '^' last, так как он будет согласован реже. Кроме того: вы намеренно делали «Землю, галактики, здания» (без пробелов) ** ** ** **? – mathguy

0

«Земля» «Земля» следует выбирать как слово в соответствии с логикой. Использование «% Earth%» также станет истинным для таких слов, как «Un-Earth» или «Earthing», и вы не хотите этого.

Так,

where (upper(col) like upper('% earth %') OR upper(col) like upper('% earth.%') OR upper(col) like upper('% earth,%')) AND 
    (upper(col) like upper('% galaxies %') OR upper(col) like upper('% galaxies.%') OR upper(col) like upper('% galaxies,%')) AND 
    upper(col) like upper('% buildings %') OR upper(col) like upper('% buildings.%') OR upper(col) like upper('% buildings,%')) 

основан на том, сколько данных поврежден, вы можете добавить несколько условий внутри OR.

Смежные вопросы