requete faisant appel a 2 tables

Eléphant du PHP | 297 Messages

17 avr. 2007, 04:21

bonjour,
Je voudrais afficher l'image des articles les + demandés...
mon pb est que les images sont sur une table et la somme des demandes sur une autre...mais le point commun entre les deux et la ref de l'article.
J'ai ecris le code pour faire la somme des demandes, je ne sais pas si il est bon, mais il ne m'affiche pas d'erreur ! :
ma premiere table demande comprends donc une colonne : article
ainsi que ma deuxieme table produit : article et image

Code : Tout sélectionner

SELECT article , SUM(article) as total FROM demande GROUP BY article DESC
Mais je ne vois pas comment joindre la premiere a la deuxieme pour afficher son image :?

si qlq peut m'aider, merci

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

17 avr. 2007, 05:54

Si j'ai bien compris, chaque enregistrement de la table "demande" contient l'identifiant d'un article. (j'espère que cet identifiant est numérique pour des questions de performance)

Pour compter le nombre d'enregistrements par article tu feras donc

Code : Tout sélectionner

SELECT article, COUNT(*) AS cnt FROM demande GROUP BY article
Maintenant, la même chose classé par ordre décroissant pour avoir les 10 plus demandés

Code : Tout sélectionner

SELECT article, COUNT(*) AS cnt FROM demande GROUP BY article ORDER BY cnt DESC LIMIT 10
Grâce à ça, tu récupères en PHP la liste des 10 articles puis tu fais une requête de type

Code : Tout sélectionner

SELECT article, image FROM produit WHERE article IN (...)
Et te voilà avec les images. Il te suffit ensuite de reparcourir la liste précédente (celle avec la liste des articles les plus demandés) et afficher l'image correspondante.

Tu peux aussi utiliser une "table dérivée" pour fusionner les deux requêtes si ça te parait plus pratique.

Code : Tout sélectionner

SELECT top.article, p.image FROM ( SELECT article, COUNT(*) AS cnt FROM demande GROUP BY article ORDER BY cnt DESC LIMIT 10 ) AS top JOIN produit p USING (article) ORDER BY top.cnt DESC

Eléphant du PHP | 297 Messages

17 avr. 2007, 14:58

Salut Hubert,
merci pour le cours.
Je l'ai mis en pratique, mais je coince la:

Code : Tout sélectionner

SELECT article, image FROM produit WHERE article IN (...)
dans l'instruction IN que dois je mettre ? la ref de tous mes articles ?

J'ai essayé la table dérivée pour fusionner, mais ca ne marche pas...
peut etre parce que les noms de colonnes de mes article est different sur mes deux tables je m'en suis rendu compte ensuite :roll:
j'ai article sur une et ref sur l'autre

Eléphant du PHP | 360 Messages

17 avr. 2007, 15:50

Essaye :

Code : Tout sélectionner

SELECT d.article, COUNT(d.article) AS cnt, p.image FROM Produit p, Demande d WHERE p.ref = d.article GROUP BY d.article, p.image ORDER BY cnt DESC LIMIT 0, 10;
Attention "LIMIT 0, 10" ne fonctionne pas sous SQL Server(sûr) et Oracle(je crois) mais sous Mysql.

Eléphant du PHP | 297 Messages

17 avr. 2007, 17:01

merci Snoops,
ça marche très bien :wink:

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

17 avr. 2007, 18:16

dans l'instruction IN que dois je mettre ? la ref de tous mes articles ?
Ben... oui.
J'ai essayé la table dérivée pour fusionner, mais ca ne marche pas...
peut etre parce que les noms de colonnes de mes article est different sur mes deux tables je m'en suis rendu compte ensuite
Premièrement, c'est pas cool de nommer ses colonnes différemment d'un table à l'autre (mais ça tu viens de t'en apercevoir). Ensuite... tu as essayé quoi comme requête exactement ? Si les colonnes portent des noms différents et que tu as une excellente raison de ne pas corriger cette erreur alors il te faut remplacer

Code : Tout sélectionner

JOIN produit p USING (article)
par (si j'ai bien compris, "article" s'appelle "ref" donc d.ref correspond à p.article ?)

Code : Tout sélectionner

JOIN produit p ON p.article = d.ref
Pour le reste, est-ce que tu pourrais effectuer un EXPLAIN de la requête que tu utilises et nous montrer le résultat stp ? L'embêtant avec la requête que propose Snoops c'est que je pense que les performances doivent pas mal chuter au fur et à mesure que ta table se remplit. Fais un EXPLAIN des deux requêtes (celle de Snoops et celle que je proposais plus haut, une fois corrigée pour ton schéma) et je t'expliquerai la différence.

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

17 avr. 2007, 19:05

Je viens de faire quelques tests informels, et si EXPLAIN donne est plutôt trompeur le temps d'exécution des requêtes confirme mes craintes. Tout dépend du serveur et des données, mais pour te donner une idée grossière de ce à quoi s'attendre pour 1000 demandes c'est à peu près 0.02s (Snoops) contre 0.01s (table dérivée). Pour 8000 demandes ça donne 0.08 contre 0.02, pour 32 000 demandes 0.70 contre 0.03, et ainsi de suite.

Pour résumer, si tu n'as jamais que quelques milliers de demandes alors le type de requête importe peu mais si le site est appelé à exister quelques années il te faudra impérativement utiliser une requête comme celle que je proposais plus haut (table dérivée ou 2 requêtes, le principe est le même).

Eléphant du PHP | 297 Messages

17 avr. 2007, 19:23

salut professeur Hubert
merci pour les infos, je note !