Pb de jointure

Signaler
Messages postés
233
Date d'inscription
mercredi 28 septembre 2011
Statut
Non membre
Dernière intervention
21 novembre 2020
-
Messages postés
233
Date d'inscription
mercredi 28 septembre 2011
Statut
Non membre
Dernière intervention
21 novembre 2020
-
Bonjour,

J'effectue deux requêtes sur ma bdd pour un moteur de recherche pour pouvoir au final classer mes résultats par popularité.
La première requête me sort les 71 produits correspondent aux mots-clefs cherchés :
SELECT ur.idprod, idkeyw, idtypekwd, note, ur.iduser 
FROM produits p
LEFT JOIN user_rates ur
ON ur.idprod = p.id
LEFT JOIN favoris_user fu ON fu.idprod = p.id
LEFT JOIN keywords k 
ON k.id = ur.idkeyw 
WHERE 
(masculin = 'huile' or feminin = 'huile'
            OR idkeyw = (SELECT master FROM keywords WHERE keyword = 'huile')
            OR nom LIKE '%huile%'
            OR keyword LIKE '%huile%') 
OR (masculin = 'apaisante' or feminin = 'apaisante'
            OR idkeyw = (SELECT master FROM keywords WHERE keyword = 'apaisante')
            OR nom LIKE '%apaisante%'
            OR keyword LIKE '%apaisante%')



La seconde me sort la note moyenne que les produits du catalogue ont obtenu sur ces critères de recherche (j'ai 2228 résultats)
SELECT idprod, nom,latin, description, idcat, categorie, pluriel,p.status, cp.genre, ident, masculin, feminin  
FROM produits p
LEFT JOIN cat_produits cp ON cp.id=p.idcat
LEFT JOIN prods_key pk ON pk.idprod = p.id
LEFT JOIN keywords k ON pk.idkeyw=k.id
LEFT JOIN keywords_types kt ON kt.idkeyword = k.id
LEFT JOIN type_keywords tk ON tk.id=kt.idtypekwd


Je voudrais pouvoir trier mes résultats par note, quitte à ne pas avoir de note pour certains produits donc j'ai fait
SELECT AVG(note) moy_users, iduser, results.idprod, nom,latin, description, idcat, categorie, pluriel, status, genre, ident, masculin, feminin 
FROM 
(ma première requête)  notes
LEFT JOIN
(ma seconde requête) results
ON notes.idprod = results.idprod

Je m'attendais à avoir 71 résultats, dont certains avec NULL pour la note (très peu sur les 71 ont été évalués) mais au lieu de ça j'ai seulement 1 résultat...
C'est bien LEFT JOIN pourtant qui retourne toutes les entrées de la première table, non ? Où est-ce que je me suis plantée ?
Configuration: Macintosh / Firefox 83.0

3 réponses

Messages postés
30256
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
21 novembre 2020
2 998
Bonjour,

AVG fonctionne avec GROUP BY


Messages postés
233
Date d'inscription
mercredi 28 septembre 2011
Statut
Non membre
Dernière intervention
21 novembre 2020
2
Je mets ici la requête complète, au cas où (je la trouvais un peu indigeste ;-) )
SELECT AVG(note) moy_users, iduser, results.idprod, nom,latin, description, idcat, categorie, pluriel, status, genre, ident, masculin, feminin 
FROM 
(SELECT ur.idprod, idkeyw, idtypekwd, note, ur.iduser 
FROM produits p
LEFT JOIN user_rates ur
ON ur.idprod = p.id
LEFT JOIN favoris_user fu ON fu.idprod = p.id
LEFT JOIN keywords k 
ON k.id = ur.idkeyw WHERE (masculin = 'huile' or feminin = 'huile'
            OR idkeyw = (SELECT master FROM keywords WHERE keyword = 'huile')
            OR nom LIKE '%huile%'
            OR keyword LIKE '%huile%') OR (masculin = 'apaisante' or feminin = 'apaisante'
            OR idkeyw = (SELECT master FROM keywords WHERE keyword = 'apaisante')
            OR nom LIKE '%apaisante%'
            OR keyword LIKE '%apaisante%'))  notes




LEFT JOIN

(SELECT idprod, nom,latin, description, idcat, categorie, pluriel,p.status, cp.genre, ident, masculin, feminin  
FROM produits p
LEFT JOIN cat_produits cp ON cp.id=p.idcat
LEFT JOIN prods_key pk ON pk.idprod = p.id
LEFT JOIN keywords k ON pk.idkeyw=k.id
LEFT JOIN keywords_types kt ON kt.idkeyword = k.id
LEFT JOIN type_keywords tk ON tk.id=kt.idtypekwd) results
ON notes.idprod = results.idprod 
WHERE idcat IN (16, 42, 43) AND(notes.iduser = 1 OR ISNULL(notes.iduser)) 
GROUP BY idprod  ORDER BY note DESC, nom ASC
Messages postés
30256
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
21 novembre 2020
2 998
par contre, je ne comprends pas trop l'utilité de faire deux sous-select
alors que tu pourrais faire toutes tes jointures dans une seule

un truc du genre
SELECT ur.idprod, idkeyw, idtypekwd, note, ur.iduser , nom,latin, description, idcat, categorie, pluriel,p.status, cp.genre, ident, masculin, feminin  
FROM produits p
LEFT JOIN user_rates ur ON ur.idprod = p.id
LEFT JOIN favoris_user fu ON fu.idprod = p.id 
LEFT JOIN keywords k ON k.id = ur.idkeyw 
LEFT JOIN cat_produits cp ON cp.id=p.idcat
LEFT JOIN prods_key pk ON pk.idprod = p.id
LEFT JOIN keywords_types kt ON kt.idkeyword = k.id
LEFT JOIN type_keywords tk ON tk.id=kt.idtypekwd
WHERE (masculin = 'huile' or feminin = 'huile'
    OR idkeyw = (SELECT master FROM keywords WHERE keyword = 'huile')
    OR nom LIKE '%huile%'
    OR keyword LIKE '%huile%') 
  OR (masculin = 'apaisante' or feminin = 'apaisante'
    OR idkeyw = (SELECT master FROM keywords WHERE keyword = 'apaisante')
    OR nom LIKE '%apaisante%'
    OR keyword LIKE '%apaisante%')
Messages postés
233
Date d'inscription
mercredi 28 septembre 2011
Statut
Non membre
Dernière intervention
21 novembre 2020
2
Oui, c'est une simple erreur de copier coller pour le group by, il figure bien sur ma requête ;-)
Par contre je me rends compte que j'ai fait une autre erreur pq en fait j'ai besoin de faire la somme des moyennes par produit (si jamais il y a plusieurs critères de recherche) et c'est pour ça que j'ai fait deux requêtes séparées, je n'ai pas su faire autrement. Sauf que j'ai fini par me planter quand même..
Je revois ça de plus près et je reviens si ça bugge toujours ! ;-)