Recherche sur table de jointure

Résolu
cs_MereDenis Messages postés 4 Date d'inscription jeudi 11 janvier 2007 Statut Membre Dernière intervention 18 avril 2009 - 13 avril 2009 à 00:35
aieeeuuuuu Messages postés 698 Date d'inscription jeudi 16 janvier 2003 Statut Membre Dernière intervention 20 mai 2011 - 20 avril 2009 à 09:55
Bonjour.

Premier post sur un forum après plusieurs tentatives de recherches infructueuses mais surement maladroites donc milles excuses si la questions a déjà été posée.

Voici ma situation :

J'ai deux tables avec une relation n:n
table notes : id, note
table mots_clefs : id, mot

que j'ai reliées par une troisième table dite "de jointure" si j'en crois mes récentes lectures en la matière :
table jointures : id_note, id_clef

Je les ai remplies par exemple comme suit :
table notes :
id     note
1      déposer des chèques à la banque
2      payer les impôts avec le sourire
3      payer les impôts avec un chèque

table mots_clefs :
id     mot
1      impôts
2      chèque

table jointures :
id_note     id_clef
1              2
2              1
3              1
3              2

Et voici donc mon problème :
Je ne parviens pas à trouver la syntaxe d'une requête SQL qui me permettrais de sélectionner "id_note" où "id_clef" = 1 et 2. Un simple " SELECT id_note FROM jointures WHERE id_clef=1 AND id_clef=2 " ne me renvoie bien sur rien.

En clair je voudrais balancer un série de mots clefs et j'aimerais que MySQL me renvoie la ou les notes qui y sont associées.

J'avais pensé à faire quelque chose du genre
SELECT id_note FROM jointure WHERE id_clef=1 OR id_clef=2 en faisant un COUNT(id_note) quelquepart puis de sélectionner les résultats où le COUNT(id_note) = nombre de mots clefs envoyés (vous l'aurez compris, je débute en SQL).

En trifouillant un peu je suis sur que ça finirait par marcher, mais sur le plan conceptuel ça ne me plait vraiment pas.
Je tourne en rond.

Il doit bien y avoir une solution plus élégante à mon problème.
Avis aux amateurs...

En espérant avoir été assez clair,
Merci d'avance.

6 réponses

aieeeuuuuu Messages postés 698 Date d'inscription jeudi 16 janvier 2003 Statut Membre Dernière intervention 20 mai 2011 3
17 avril 2009 à 11:11
je pense que je comprend un peu mieux.
en fait tu veux les note qui contiennent TOUS les mots clefs

alors je verrai plutot ca :

SELECT * FROM notesWHERE id IN (SELECT id_note FROM jointure WHERE id_clef (SELECT id FROM mots_clef WHERE mot 'mot 1'))AND id IN (SELECT id_note FROM jointure WHERE id_clef (SELECT id FROM mots_clef WHERE mot 'mot 2'))AND id IN (SELECT id_note FROM jointure WHERE id_clef (SELECT id FROM mots_clef WHERE mot 'mot 3'))

c'est un peu lourd comme ca, mais si tu etablit ta requete a partir d'un langage genre PHP, c'est peut etre la solution la plus simple

sinon il doit effectivement y avoir une solution avec un COUNT, mais après tout depend de comment tu recupere tes mots clefs a chercher (es tu sur que les mots clefs saisis seront EXACTEMENT les meme que les mots clef dans la base ?)
3
cs_MereDenis Messages postés 4 Date d'inscription jeudi 11 janvier 2007 Statut Membre Dernière intervention 18 avril 2009
13 avril 2009 à 08:33
Re-bonjour.

Ca m'a travaillé toute la nuit mais je crois que j'ai trouvé un semblant de solution :

SELECT DISTINCT id_note FROM jointures AS t1 CROSS JOIN jointures AS t2 USING(id_note) CROSS JOIN jointures AS t3 USING(id_note) [...] WHERE t1.id_clef=x AND t2.id_clef=y AND t3.id_clef=z [...];

Je sais pas si c'est l'idéal mais d'après mes premiers tests ça fonctionne comme souhaité et ça permet de faire des recherches avec autant de mots clefs que je le veux.
Et c'est tout de même plus "propre" que mes premières idées.

Est-ce que les habitués de bases de données peuvent me donner leur avis sur mon aproche du problème ?
Que ce soit au niveau de la conception de mes tables ou de ma requête SQL, toutes les critiques sont les bienvenues.

Bonnes fêtes de Paques !
0
aieeeuuuuu Messages postés 698 Date d'inscription jeudi 16 janvier 2003 Statut Membre Dernière intervention 20 mai 2011 3
14 avril 2009 à 10:24
Bonjour

a premiere vue, je dirai qu'il n'y a pas d'erreur conceptuelle sur la base en elle même.

pour récuperer les Notes, tu peux faire comme ca :
SELECT *
FROM Notes N
INNER JOIN jointures J ON (N.id = J.id_note)
INNER JOIN mots_clef C ON (J.id_clef = C.id)
WHERE C.mot IN ('Mot1', 'Mot2','Mot3',...)

voila, ca n'est qu'un exemple, après ca depend de ce que tu veux en faire (tu peux par exemple trier par le plus grand nombre de resultats...)
0
cs_MereDenis Messages postés 4 Date d'inscription jeudi 11 janvier 2007 Statut Membre Dernière intervention 18 avril 2009
16 avril 2009 à 10:37
OK pour les tables, mais pour la requête, celle que tu me propose ne convient pas parcequ'avec la clause

WHERE C.mot IN ('Mot1', 'Mot2', 'Mot3',...)

il me retourne toutes les notes qui sont associées au mot 1 plus toutes celles associées au mot 2 etc or moi je voudrais qu'il me retournes uniquement les notes associées aux mots 1 ET 2 ET 3 etc.
D'où ma requête un peu tordue donnée plus haut.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_MereDenis Messages postés 4 Date d'inscription jeudi 11 janvier 2007 Statut Membre Dernière intervention 18 avril 2009
18 avril 2009 à 20:59
Comme tu dis la requête est un peu lourde mais comme je vais bien utiliser du php en amont ça devrait le faire.
Et le php devrait également vérifier la pertinence des mots-clefs.

Merci pour les conseils !
0
aieeeuuuuu Messages postés 698 Date d'inscription jeudi 16 janvier 2003 Statut Membre Dernière intervention 20 mai 2011 3
20 avril 2009 à 09:55
de rien ;)
0
Rejoignez-nous