Pb de jointure

ephelya Messages postés 296 Statut Membre -  
ephelya Messages postés 296 Statut Membre -
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

  1. jordane45 Messages postés 30426 Date d'inscription   Statut Modérateur Dernière intervention   4 830
     
    Bonjour,

    AVG fonctionne avec GROUP BY

    0
  2. ephelya Messages postés 296 Statut Membre 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
    0
    1. jordane45 Messages postés 30426 Date d'inscription   Statut Modérateur Dernière intervention   4 830
       
      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%')
      
      0
  3. ephelya Messages postés 296 Statut Membre 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 ! ;-)
    0