Classer les résultats d'un count (2 tables)

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Classer les résultats d'un count (2 tables)

par Truc » 01 janv. 2008, 18:49

Modération :
karenma, si tu as une question dans le même style que l'auteur de ce sujet ouvre en un nouveau ,cela te permettra d'avoir plus de réponses.

En plus, tu pourras mettre [Résolu] dès que ton problème évoqué ici sera réglé.

Merci de prendre le temps de lire les règlements.

par Sékiltoyai » 01 janv. 2008, 13:22

Quand dans une requète sql, tu mets "machin as c" ou bien "machin c", dans la clause SELECT ou la clause FROM (ou quelques autres mais après il faut voir le manuel), tu déclare un alias nommé par le membre de droite (ici "c") vers l'expression à gauche (qui peut être un nom de champ, de table, ou bien une expression plus complexe comme le résultat d'une fonction).

Donc, dans ce cas, à chaque fois dans la requète que tu vois un c isolé, MySQL considère que c'est "COUNT(boite_op_rep)" puisque c est un alias vers "COUNT(boite_op_rep)". Et même, lorsque le résultat est renvoyé à l'utilisateur, MySQL utilise le nom de l'alias, c'est à dire c, pour désigner le champ de résultat (si tu utilises mysql_fetch_array() en clés non numériques, mysql_fetch_assoc(), ou encore mysql_fetch_object()), et non l'expression complète, comme il le fait normalement.

je ne comprends pas

par karenma » 01 janv. 2008, 11:31

salut j'ai essayé de comprendre ton programme à la fin car j'essaye de faire un petit peu la même chose mais je ne comprend pas c'est quoi ce c dans ton programme

Code : Tout sélectionner

SELECT COUNT(boite_op_rep) as [b][b]c[/b][/b], boite_id, boite_titre bon tu vas surement pensé que je ne comprends rien du tout mais c pas facile de se mettre au php Merci d'avance pour ta réponse

par AB » 02 déc. 2007, 21:06

Pour répondre par avance à une question qui pourrait se poser : trier en fonction du nombre de vote et en fonction de la date de l'article.
Par exemple pour classer de la plus récente à la plus ancienne, les news ayant le même résultat au vote, il suffit de rajouter une seconde clause dans le order by
$sql="SELECT COUNT(boite_op_rep) as c, boite_id, boite_titre  
FROM boite 
LEFT JOIN  boite_op  
ON boite_op_ididee = boite_id 
WHERE boite_op_rep = 1 
GROUP BY boite_id  
ORDER BY c DESC,  boite_id DESC
LIMIT 10";
Voilà, je crois qu'on a fait le tour de ce sujet 8-)

(@ Liza, la prochaine fois, quelque soit ton profil, penses à t'inscrire sinon tu vas te faire rayer les côtes par un tigre à dent de sabre et j'aimerais pas être à ta place :lol: )

par Invité » 02 déc. 2007, 17:10

Merci Truc. Comme j'ai dit, je m'inscris au prochain topic que je créerai... au risque de demander plus d'aide que d'en donner :lol:

Merci encore, votre communauté est vraiment sympa :wink:

par Truc » 02 déc. 2007, 13:23

Le schéma des tables devait surtout servir à trouver cette fameuse requête plus rapidement et non pas pour faire style :wink:

Modération :
Puisque ta question est résolue, j'ajoute le tag [Résolu]
pour indiquer aux personnes qui voudront consulter ce sujet qu'il contient une solution.

Tu peux réaliser cette opération toi-même
en cliquant sur le bouton Image qui s'affiche en haut à gauche de ce sujet
si tu as posté le 1er message en tant que membre (inscrit et identifié).

Alors... inscris-toi !!! ;)

par Liza » 02 déc. 2007, 07:37

[Réglé]

Tu ferais mieux de t'inscrire, tu pourrais éditer tes messages et tu n'aurais plus à te soucier d'entrer un pseudo.
Effectivement. Le fait est que je ne veux pas que l'historique de mes messages ne comprenne uniquement des demandes d'aide :lol: Je pense qu'un forum marche dans les deux sens :wink: Mais c'est promis, si je dois poster un nouveau topic alors ce sera avec un vrai pseudo :wink:


J'ai finalement aboutit à ce que je souhaitais grâce à la dernière méthode que m'a proposé AB. Le problème du LIMIT venait d'une mauvais manip' avec ma boucle mais ça y est c'est réglé.


Voici le code final. Pour ceux qui m'ont aidé, et celà pourra peut-être aussi aider d'autres personnes. En tout cas grâce à vous et notamment AB, je sais maintenant comment faire une jointure dans un SELECT :wink: Je devrais veiller à l'avenir à ce que mon code soit propre.
$i=0;

$sql="SELECT COUNT(boite_op_rep) as c, boite_id, boite_titre  
FROM boite 
LEFT JOIN  boite_op  
ON boite_op_ididee = boite_id 
WHERE boite_op_rep = 1 
GROUP BY boite_id  
ORDER BY c DESC 
LIMIT 10";

$query=mysql_query($sql);
while($data = mysql_fetch_array($query))
{

    $i++;

    echo "<span class='txt_black_bold'>&nbsp;•<a class='txt_black_bold' title='".count['boite_titre']."' href='index.php?c=boiteaidees&view=zoom&id=".$data['boite_id']."'><span class='$couleur'>[$i]</span> ".substr($data['boite_titre'],0,30)."[...]</a></span><br /><span class='txt_black'>&nbsp;Opinions favorables : <b>".$data['0']."</b></span><br />";
}
Et voici la shéma de mes tables :

Code : Tout sélectionner

-- Version du serveur: 4.1.9 CREATE TABLE boite ( boite_id int(11) unsigned NOT NULL auto_increment, boite_date int(11) NOT NULL default '0', boite_date_rss text NOT NULL, boite_date_update int(11) NOT NULL default '0', boite_date_last int(11) NOT NULL default '0', boite_titre text NOT NULL, boite_desc text NOT NULL, boite_auteur_id int(11) NOT NULL default '0', boite_rub text NOT NULL, boite_vu int(11) NOT NULL default '0', PRIMARY KEY (boite_id) ); CREATE TABLE boite_op ( boite_op_id int(11) unsigned NOT NULL auto_increment, boite_op_ididee int(11) NOT NULL default '0', boite_op_auteur_id int(11) NOT NULL default '0', boite_op_rep int(11) NOT NULL default '0', PRIMARY KEY (boite_op_id) );
AB : Il s'agit donc de la solution la mieux adaptée pour ce que je veux faire. D'ailleurs tu l'évoquais toi-même hier :
Du coup tu devrais pouvoir te passer des champs que je t'ai conseillé de rajouter :P quoique je me demande si tu n'a pas intérêt à les garder pour avoir une requête plus rapide que celle-ci :-k

Tu n'avais pas posté dans la bonne rubrique (sql) donc tu n'a pas pu voir le message qui t'indiquait de poster le schéma te tes tables et donc mon conseil n'était pas nécessairement le plus adapté* puisqu'il faut que tu conserve ta deuxième table :wink:
* Valable aussi pour ce message.

Je vous réitère tous mes remerciements concernant votre aide qui m'a été très précieuse et qui m'aidera à l'avenir. Un grand merci particulier à AB qui a su très vite cerner mon problème (on reconnait bien les experts en la matière 8-) ).


Au plaisir de vous lire,

Amicalement Liza.

par Hubert Roksor » 02 déc. 2007, 00:20

Tu ferais mieux de t'inscrire, tu pourrais éditer tes messages et tu n'aurais plus à te soucier d'entrer un pseudo.

Sans oublier ça :
Je déplace... poste nous le schéma des tables pour qu'on puisse faire des tests

par Liza » 02 déc. 2007, 00:16

Et une fois de plus j'oublie de renseigner mon pseudo dans le post précédent. Veuillez m'en excuser :oops:

Liza.

par Invité » 02 déc. 2007, 00:15

Sous réserve, l'équivalent de ta première méthode "sale" pourrait ressembler...
AB, c'est exactement ce que je cherchais ! 3 jours pour enfin trouver le "bon SELECT". Après 3 jours de recherche, je suis bien-sûr tombée sur le principe des jointures. Je n'ai jamais essayé votre méthode car j'admets ne pas avoir bien assimilé le principe des "tables de gauche" et "table de droite" (mais je m'y attelle !). En effet celà pourra m'éviter de faire des SELECT dans une boucle... :roll:

Il me reste néanmoins un petit souci : malgré un DESC LIMIT, il ne me sort qu'un seul résultat (le plus fort, celui qui est le mieux noté). Ci-dessous mon code selon ton dernier conseil, et aussi comme promis le shéma de mes tables (j'ai préféré une image, pour plus de clarté, j'espère que ceci n'est pas dérangeant :wink: ) :

Image

Ce qui donne :
$sql="SELECT count(vote_result) as c, boite_id, boite_titre  
FROM boite 
LEFT JOIN  boite_vote 
ON vote_idboite = boite_id 
WHERE vote_result = 1 
GROUP BY boite_id  
ORDER BY c DESC 
LIMIT 5";

$query=mysql_query($sql);
$data = mysql_fetch_array($query);

echo "Idée : ".$data['boite_titre']." / Nombre de votes positifs : ".$data['0']";
Du coup tu devrais pouvoir te passer des champs que je t'ai conseillé de rajouter :P quoique je me demande si tu n'a pas intérêt à les garder pour avoir une requête plus rapide que celle-ci :-k

Tu n'avais pas posté dans la bonne rubrique (sql) donc tu n'a pas pu voir le message qui t'indiquait de poster le schéma te tes tables et donc mon conseil n'était pas nécessairement le plus adapté* puisqu'il faut que tu conserve ta deuxième table :wink:
* Valable aussi pour ce message.
Si je résouds le problème du DESC LIMIT, je pense que je garderai cette méthode, bien que celle-ci complique effectivement la tâche du serveur (le système d'incrémentation +1 / -1 directement dans la table "boite" aurait été tellement plus simple). Mais comme je l'avais précisé précédemment, je suis quoi qu'il en soit obligée de garder une 2e table, ne serait-ce que pour enregistrer l'ID du membre et ainsi l'empêcher de voter une 2e fois.


En tout cas, je vous remercie tous d'ores et déjà :wink: Les forums d'entre-aide, quels qu'ils soient, sont selon moi les plus belles réussites du Net :wink:

par AB » 01 déc. 2007, 21:21

Sous réserve, l'équivalent de ta première méthode "sale" pourrait ressembler à
"
SELECT count(vote_result) as c, news_id, news_article 
FROM articles
LEFT JOIN  article_vote 
ON vote_idarticle = news_id
WHERE vote_result = 1
GROUP BY news_id 
ORDER BY c DESC
LIMIT 10"
- LIMIT 10 uniquement si tu veux ne lister que les 10 premières news ayant le meilleur score
- J'ai mis news_article dans le SELECT pour que tu puisses récupérer la news. Peut-être news_titre pour ne récupérer que le titre pourrait suffire.

EDIT
Du coup tu devrais pouvoir te passer des champs que je t'ai conseillé de rajouter :P quoique je me demande si tu n'a pas intérêt à les garder pour avoir une requête plus rapide que celle-ci :-k

Tu n'avais pas posté dans la bonne rubrique (sql) donc tu n'a pas pu voir le message qui t'indiquait de poster le schéma te tes tables et donc mon conseil n'était pas nécessairement le plus adapté* puisqu'il faut que tu conserve ta deuxième table :wink:
* Valable aussi pour ce message.

par Liza » 01 déc. 2007, 21:13

PS : le message ci-dessus est le mien (Liza). Désolé j'ai oublié de renseigner mon pseudo (oui oui, ça ne serait pas arrivé si je m'étais inscrite... :lol: )

par Invité » 01 déc. 2007, 21:12

Merci à tous de votre intérêt. Ok je vous posterai le shéma des tables ce soir. Celà dit j'ai réglé le problème depuis (en suivant le premier conseil d'AB). J'ai créé un nouveau champ "note" directement dans la table des news. Par contre, j'ai tout de même gardé la 2e table avec l'ID de la news et l'ID et l'ID du membre (pour éviter que le membre vote 2 fois la même news). Et, pardonnez-moi si je me trompe, mais je ne pouvais pas placer cette condition directement dans la table des news.

En apprenant les jointures depuis quelques jours, je me suis focalisée là-dessus en me disant que c'était la meilleure solution. Mais c'est vrai qu'en PHP il ne faut jamais rester buté sur une solution et une seule, alors qu'il y en a toujours une autre pas loin :wink:


Mais normalement cette requête ne te renverras pas tes news. Si je ne me trompe, elle devrait te renvoyer le même résultat que
$sql_count="SELECT count(vote_result) FROM article_vote WHERE vote_result='1'"; 
Effectivement, si j'ai bien compris, du fait qu'il s'agisse d'un COUNT(), je ne pourrais pas récupérer les valeurs dans les tables (exemple un titre, un article), mais juste un résultat. C'est d'ailleurs pour celà que j'étais partie sur l'idée de faire un SELECT et un SELECT COUNT dans la même requête. Par contre, ta requête AB ne comptera que le nombre de votes positifs, toutes les news confondues, alors que je cherchais justement à compter le nombre de votes positifs, mais par news.



Je vous montrerai le shéma ce soir, basé sur le premier conseil d'AB de ce matin.

Merci à tous en tout cas, y'a pas à dire, je bosse sur PHP depuis 1 an et j'ai toujours essayé de trouver les solutions sur les forums, sans poster de nouveau topic. Mais parfois on est obligé :lol: Je ne me suis pas inscrite sur votre forum car j'ai du poster 2 topics en 1 an. Je m'y inscrirai le jour où je serai moi-même en mesure d'aider les autres (autant dire ce n'est pas encore acquis :lol: ).

A tout à l'heure donc :wink:

par AB » 01 déc. 2007, 18:37

Admettons, comme ça, ça irait mieux ? :arrow:
$sql_count="SELECT count(vote_result) FROM article,article_vote WHERE article_vote.vote_idarticle=article.news_id AND article_vote.vote_result='1'"; 
(En admettons bien-sûr que le résultat du vote se trouve toujours sur une 2e table. Même si ce n'est pas la meilleure solution et qu'il ne s'agit que d'une ébauche, j'aimerais juste avoir votre avis :wink: )
Effectivement sur le principe c'est beaucoup mieux :)

Mais normalement cette requête ne te renverras pas tes news. Si je ne me trompe, elle devrait te renvoyer le même résultat que
$sql_count="SELECT count(vote_result) FROM article_vote WHERE vote_result='1'"; 
Il faudrait suivre le conseil de Truc et nous poster le schéma de tes tables car sinon on risque de te donner des conseils non adaptés, comme mon précédent message qui te proposait de supprimer la table vote parce que tu n'avais pas indiquer tous les champs :wink:

Re: Classer les résultats d'un count (2 tables)

par Truc » 01 déc. 2007, 12:08

D'avance merci :wink: En espérant ne pas m'être trompée de forum.
On va dire que si :wink:
Je déplace... poste nous le schéma des tables pour qu'on puisse faire des tests