Trier une requète par le nombre d'occurrences trouvée dans une relatiom ManytoMany

a marqué ce sujet comme résolu.

J’ai trois tables:

plats:

id title
16 Tartiflette
17 Salade
18 Nouilles
19 Lazagnes

ingredients:

id name
123 Pâtes
124 Tomates
125 Courgette
126 Crème
127 Oeufs
128 Mozzarella

plats_ingredients

r_id t_id
16 126
16 127
16 123
16 128
17 128
17 123
18 127
18 126

Je retrouve très bien les plats associés au ingrédients mais aujourd’hui, j’aimerais que lorsque une liste d’ingrédient est recherchée, les plats associés soit trouvés ordonné dans l’ordre du nombre d’ingrédients recherchés qu’ils contiennent afin que l’utilisateur voit en premier les resultats qui correspondent le mieux à sa recherche:

Exemple:

Recherche: Pâtes, Oeufs, Mozzarella

Résultats:

Tartiflette (n°1 contient Oeuf, Pâtes, Mozzarella) Salade (n°2 contient Pâtes, Mozzarella) Nouilles (n°3 contient Oeuf)

Merci pour vôtre aide.

+0 -0

Salut,

Ton problème intéressant, une solution simple est de se dire qu’avec les jointures, tu vas pouvoir lister tous les plats qui correspondent à chacun des critères. Et que si un plat correspond à plusieurs critères, il sera trouvé plusieurs fois.

Il te suffit alors de grouper sur ce plat et d’ordonner par nombre d’occurrences.

Cela te donnerait une requête comme ça :

SELECT title
  FROM plats
       LEFT JOIN plats_ingredients
       ON plats.id=r_id
       INNER JOIN ingredients
       ON ingredients.id=t_id
 WHERE name IN ('Pâtes', 'Oeufs', 'Mozzarella')
 GROUP BY title
 ORDER BY COUNT(title) DESC

C’est une solution assez naïve et je n’ai pas du tout regardé ce que ça donnait question performances, peut-être y a-t-il moyen de faire mieux avec des sous-requêtes plutôt qu’un GROUP BY ?

PS : bizarre la mozza dans la tartiflette :D

Ton problème intéressant, une solution simple est de se dire qu’avec les jointures, tu vas pouvoir lister tous les plats qui correspondent à chacun des critères. Et que si un plat correspond à plusieurs critères, il sera trouvé plusieurs fois.

entwanne

Merci pour ton aide ! cette formulation me rend la solution claire. Au niveau des performances, je pense que j’aurais bien d’autres problèmes avant celui-là (et j’avoue aussi ne rien trouver de mieux après quelques tests)

PS : bizarre la mozza dans la tartiflette :D

entwanne

Ces donnée sont fictives, aucune tartiflette n’a été blessée dans la BDD ^^ .

Certe la réponse d' entwanne donne la réponse "sur un plateau".

Cependant, les explications associées:

sur la composition de la requête:

Et que si un plat correspond à plusieurs critères, il sera trouvé plusieurs fois.

Il te suffit alors de grouper sur ce plat et d’ordonner par nombre d’occurrences.

entwanne

et sur la partie de la requête qui me manquait:

 GROUP BY [plats.]title
 ORDER BY COUNT([plats.]title) DESC

entwanne

m’apporte des données utiles.

Ta réponse évoque les "mots clefs" à utiliser dans la requête, mais de mon point de vue, connaissant ces mots clefs et ne sachant pas comment les utiliser dans le cadre d’une relation many-to-many, elle ne me semble pas apporter d’informations utiles. Quelques précisions supplémentaires aurait été appréciées.

Alors loin de moi l’idée de vouloir donner une solution toute faite, mais la syntaxe et la logique du SQL étant ce qu’elles sont, je trouvais plus simple d’illustrer mon propos avec le code, pour voir comment s’agencent ces différents mot-clés.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte