2010-10-22 10 views
4

Merci d'avoir lu ceci. J'espère que tu peux m'aider.

Quand j'ai une table Mysql avec ces valeurs pour la ligne
correspondance inverse de plusieurs mots

id | recherche
========
1 | papillons
2 | Amérique
3 | oiseaux d'Amérique
4 | Comment puis-je dire quelles lignes ont tous les mots dans la colonne «recherche» se produisant dans la chaîne «papillons d'Amérique», quel que soit le nombre ou l'ordre des mots de recherche. Je voudrais récupérer 1,2 et 4 dans cet exemple) J'utilise maintenant une boucle codée pour résoudre ce problème, ce serait sympa de le résoudre plus efficacement avec mysql. J'ai essayé la recherche en texte intégral et les expressions régulières, mais je suis complètement coincé. Tx.

Répondre

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

ou

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

Si je ne suis pas manque quelque chose :)

Edit: je manque quelque chose :(

+0

Wow, réponse rapide, merci! J'ai essayé vos suggestions. Votre premier SELECT ne renvoie que les enregistrements 1 et 2, mais je voudrais aussi récupérer 4 ("america" ​​et "butterflies" apparaissent dans la chaîne). Le second SELECT retourne tous les enregistrements, mais je ne veux pas enregistrer 3 ('birds' n'apparait pas dans la chaîne).Des idées sur la façon de modifier l'expression rationnelle? – wikkie

+0

Maintenant, j'ai réalisé ce que vous voulez. Va venir avec la solution bientôt j'espère :) –

+0

Ok, essayé à nouveau et maintenant la requête ne renvoie aucun enregistrement; il demande des enregistrements qui contiennent tous les mots (butterflies + of + america), et aucun des enregistrements ne contient tous les mots. Changer le AND en OR ne fait rien de bien (retourne tous les enregistrements à nouveau). – wikkie

0

Voici une méthode que j'ai expérimenté avec (mais pas très efficace):

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; 

Cette requête vous donnera quelque chose comme ce qui suit:

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

La dernière pièce à faire ce travail me donnait des ennuis, mais ... vous avez besoin d'une clause where qui renverra toutes les lignes qui sont « vides " (c'est à dire ne contient que des caractères blancs).

Cela va filtrer la troisième ligne et retourner le jeu de résultats que vous désirez. Cependant, je n'ai pas réussi à faire fonctionner ceci avec trim() et je ne sais pas pourquoi.

Par exemple, j'ai essayé:

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

Cela ne me donne pas le jeu de résultats que je voulais. Je n'ai plus le temps de me pencher là-dessus, mais je voulais mentionner cette approche au cas où quelqu'un d'autre voudrait intervenir et finir de résoudre le puzzle. Si ce n'est pas le cas, j'essaierai d'en parler un peu plus tard aujourd'hui ou demain.

+0

Bonjour Matt, j'aime vraiment votre approche intelligente. Mais ne pensez-vous pas que cette méthode produirait une requête lente? L'imbrication dépendra également du code pour produire une requête appropriée. J'espère toujours trouver une solution indépendante du code. :-) – wikkie

+0

Je suis d'accord, ce n'est peut-être pas la requête la plus performante, mais la performance serait probablement acceptable. Un framework de persistance tel que ibatis/mybatis (http://www.mybatis.org/java.html) pourrait être utilisé pour générer des requêtes dynamiques comme celle-ci en dehors du code. –

1

Remplacements imbriqués, pas de sous-requêtes.

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 

j'ai ajouté des espaces bookending aux mots de recherche pour vous assurer de ne correspondent pas contre le milieu des mots (par exemple « de » dans « café »). En outre, j'ai ajouté des serre-livres de l'espace à la phrase search pour tenir compte du premier et du dernier mot.

Questions connexes