2010-10-22 3 views
4

Спасибо, что прочитали это. Надеюсь, ты поможешь мне.

Когда у меня есть таблица Mysql с этими значениями строками
обратное совпадение нескольких слов

идентификатора | поиск
========
1 | бабочки
2 | америка
3 | птицы Америки
4 | america butterflies

Как я могу определить, какие строки имеют все слова в столбце «поиск», происходящие в строке «бабочки америки», независимо от количества или порядка слов поиска.

(я хотел бы получить 1,2 и 4 в этом примере) Теперь я использую закодированный цикл для решения этой проблемы, было бы неплохо исправить его более эффективно с помощью mysql. Я пробовал полнотекстовый поиск и регулярные выражения, но полностью застрял. Tx.

ответ

0
SELECT * 
FROM table_name 
WHERE search LIKE '%butterflies%' 
    AND search LIKE '%of%' 
    AND search LIKE '%america%'; 

или

SELECT * 
FROM table_name 
WHERE search REGEXP 'butterflies|of|america'; // not working 

Если я не хватает чего-то :)

Edit: я что-то :(

+0

Ничего себе, быстрый ответ, спасибо! Я попробовал ваши предложения. Ваш первый SELECT возвращает только записи 1 и 2, но я также хотел бы получить 4 (в строке есть как «америка», так и «бабочки»). Второй SELECT возвращает все записи, но мне не нужна запись 3 («птицы» не встречаются в строке).Любые мысли о том, как настроить регулярное выражение? – wikkie

+0

Теперь я понял, чего вы хотите. Скоро придет с решением :) –

+0

Хорошо, попробовал еще раз, и теперь запрос не возвращает никаких записей; он запрашивает записи, содержащие все слова (бабочки + + америки), и ни одна из записей не содержит всех слов. Изменение AND в OR не делает ничего хорошего (возвращает все записи снова). – wikkie

0

Вот один метод, который я экспериментировал с отсутствующими (хотя и не очень эффективны):

select search, replace(filtered, 'butterflies', '') as filtered from (
    select search, replace(filtered, 'of', '') as filtered from (
     select search, replace(search, 'america', '') as filtered from table_name a 
    ) b 
) c; 

Этот запрос даст вам что-то вроде следующего:

+---------------------+----------+ 
| search    | filtered | 
+---------------------+----------+ 
| butterflies   |   | 
| america    |   | 
| birds of america | birds | 
| america butterflies |   | 
+---------------------+----------+ 

Последняя часть, чтобы сделать эту работу дает мне некоторые проблемы, хотя ... вам нужно где положение, которое возвращает все строки, которые «пустой "(т.е. содержат только пробельные символы).

Это будет отфильтровывать третий ряд и возвращать желаемый результат. Тем не менее, я не смог заставить это работать, используя trim(), и я не знаю почему.

Например, я попробовал:

where length(trim(c.filtered)) = 0; 

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

+0

Привет, Мэтт, я действительно люблю твой умный подход. Но разве вы не думаете, что этот метод вызвал бы медленный запрос? Вложение также будет зависеть от кода для создания правильного запроса. Я все еще надеюсь найти решение, не зависящее от кода. :-) – wikkie

+0

Согласен, это может быть не самый эффективный запрос, но производительность, вероятно, будет приемлемой. Для создания динамических запросов, таких как вне кода, можно использовать инфраструктуру сохранения, такую ​​как ibatis/mybatis (http://www.mybatis.org/java.html). –

1

Вложенные заменяет, нет подзапросов.

SELECT id, search 
FROM a 
WHERE LENGTH(TRIM( 
REPLACE(REPLACE(REPLACE( 
CONCAT( ' ', search, ' ') , 
' butterflies ', ' ') , ' of ', ' ') , ' america ', ' '))) = 0 

     id search 
     1 butterflies 
     2 america 
     4 america butterflies 

Я добавил bookending пространства на слова для поиска, чтобы убедиться, что вы не совпадают по отношению к середине слова (например, «из» в «кофе»). Более того, я добавил пространственные книги к фразу search, чтобы учесть первые и последние слова.

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