problème ORDER BY !

Eléphant du PHP | 259 Messages

13 mars 2007, 12:27

Bonjour,

J'ai une page qui affiche un sondage (question et réponses) avec le nombre de pourcentage par réponse.

J'aimerais ordonné les réponses en fonction des pourcentages, du plus grand au plus petit.. mais je ne sais pas comment faire...

voici une partie de mon code :
<?

$sql = "SELECT * FROM question where id_sondage ='$id_sondage' ORDER BY position ASC"; 
$req = mysql_query($sql); 

$total = mysql_num_rows($req); 

if ($total == 0) 
    { 
    echo'<u><p><h1>Il n\'y a aucune question</p></u></h1>'; 
    } 

    else if ($total > 0) 
        { 
        $i=1;  //on met la variable a 1     
        while($valeur = mysql_fetch_array($req)) 
            {    
			//Récupére les données des qestions
            $titre_question =  $valeur['titre_question']; 
            $id_question = $valeur['id_question']; 
            $methode = $valeur['methode']; 

			echo '<p> </p>';
				//Affiche le numéro et le titre de la question
				echo'<table border="0" width=95%><tr><td></td></tr><tr><tr><td></td></tr><td align = "left"><h1>'.$i.') '.$titre_question.'</h1></td><tr><td></td></tr><tr><tr><td></td></tr></table>';	
                                                
                    //Requête pour récupérer les données des réponses 
	
					$requete2 = "SELECT * FROM reponse WHERE id_sondage = '$id_sondage' AND id_question = '$id_question'  ORDER BY position ";    
                    $resultat2 = mysql_query($requete2) or die ('Erreur SQL : impossible d\'effectuer la requête : <br />'.$requete2); 
                    $total = mysql_num_rows($resultat2); 
                    if ($total == 0) 
						{ 
						echo'<u><h1>Il n\'y a aucune réponse</u></h1>'; 
						}
						else if ($total > 0) 
                        { 
                           while($val= mysql_fetch_array($resultat2)) 
                            { 
							$id_reponse = $val['id_reponse']; 
							$intitule = $val['intitule']; 

                            ?> 
                            <html> 
                            <body> 
                            <div align ="center">        
                            <TABLE border="0"> 
                            <?   
							
							//Suivant la méthode							
							switch ($methode) 
							{ 
//Liste déroulante 
							case 'deroulante': 
							//Récupére le nombre de réponse total								
							$req1 = "SELECT count(id_reponse) FROM vote WHERE id_sondage = '$id_sondage' AND id_question = '$id_question'  "; 
							$resultat1 = mysql_query($req1); 
								while($val1= mysql_fetch_array($resultat1)) 
								{ 
								$nb_rep = $val1['count(id_reponse)']; 
								}
								
							if ($nb_rep > 0)
							{
							$req4 = "SELECT * FROM vote WHERE id_sondage = '$id_sondage' AND id_question = '$id_question'  AND id_reponse = '$id_reponse'  "; 
							$resultat4 = mysql_query($req4); 
							$nb_vote = mysql_num_rows($resultat4);

							$pourcent =  cacul_pourcentage($nb_vote,$nb_rep);
		
							echo'<table border="0" width="88%"><tr>';
							echo'<td width="7%">'.$intitule.' : ';
							echo'</td><td width="7%"><img src="image.php?p='.$pourcent.' align="left" >';
							echo'</td><td width="2%">'.$pourcent.' %';
							echo'</td></tr></table>'; 
							}
							break; 
	            
							//Bouton radio 
							case 'radio': 
							//Récupére le nombre de réponse total								
							$req1 = "SELECT count(id_reponse) FROM vote WHERE id_sondage = '$id_sondage' AND id_question = '$id_question'"; 
							$resultat1 = mysql_query($req1); 
								while($val1= mysql_fetch_array($resultat1)) 
								{ 
								$nb_rep = $val1['count(id_reponse)']; 
								}

							if ($nb_rep > 0)
							{
							$req4 = "SELECT * FROM vote WHERE id_sondage = '$id_sondage' AND id_question = '$id_question'  AND id_reponse = '$id_reponse' "; 
							$resultat4 = mysql_query($req4); 
							$nb_vote = mysql_num_rows($resultat4);
							
							
							$pourcent =  cacul_pourcentage($nb_vote,$nb_rep);
														
							
							echo'<table border="0" width="88%"><tr>';
							echo'<td width="7%">'.$intitule.' : ';
							echo'</td><td width="7%"><img src="image.php?p='.$pourcent.' align="left" >';
							echo'</td><td width="2%">'.$pourcent.' %';
							echo'</td></tr></table>'; 
							}
							
							break; 

							case 'checkbox': 
							//Récupére le nombre de réponse total								
							$req1 = "SELECT count(id_reponse) FROM vote WHERE id_sondage = '$id_sondage' AND id_question = '$id_question' ORDER BY id_vote"; 
							$resultat1 = mysql_query($req1); 
								while($val1= mysql_fetch_array($resultat1)) 
								{ 
								$nb_rep = $val1['count(id_reponse)']; 
								}
							
							if ($nb_rep > 0)
							{
							$req4 = "SELECT * FROM vote WHERE id_sondage = '$id_sondage' AND id_question = '$id_question'  AND id_reponse = '$id_reponse' ORDER BY id_vote"; $resultat4 = mysql_query($req4); 
							$nb_vote = mysql_num_rows($resultat4);
							
							$pourcent =  cacul_pourcentage($nb_vote,$nb_rep);
		
							echo'<table border="0" width="88%"><tr>';
							echo'<td width="7%">'.$intitule.' : ';
							echo'</td><td width="7%"><img src="image.php?p='.$pourcent.' align="left" >';
							echo'</td><td width="2%">'.$pourcent.' %';
							echo'</td></tr></table>'; 
							}
							break; 
     
                            }//fin switch 

                            }//fin while      
							//s'il n'y a aucune réponse, on affiche un message
							if ($nb_rep == 0)
							{
							echo'<table border="0" width=30%><td align="left"><u><ul> Il n\'y aucune réponse </td></ul></u></table>';
							}							
                        } //fin du if
				$i++; // incrément le i avant la fin de la boucle
            } //fin du while
        }//fin else if (dc pour afficher) 

?<
calcu_pourcentage est une fonction qui calcul le pourcentage.
Je pense que je doit modifier cette ligne :
<?
$requete2 = "SELECT * FROM reponse WHERE id_sondage = '$id_sondage' AND id_question = '$id_question'  ORDER BY position "; 
?>
Peut etre mettre ORDER BY '.$pourcent.'"; mais ça ne marche pas car le pourcentage je le calcul aprés.

J'espére que vous pourrez m'aider!

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

13 mars 2007, 12:55

Montre nous comment tu calcules le pourcentage et on essayeras de l'intégrer dans la requête.

En effet, seuls les champs présents dans la requête peuvent être dans le ORDER BY :?

PS : essaye d'éviter les "SELECT *", tu remontes surement plus de volume de données que nécessaire. Prend l'habitude de nommer explicitement les champs que tu remontes ;)
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Eléphant du PHP | 259 Messages

13 mars 2007, 12:57

Voici ma fonction qui calcul un pourcentage :

Code : Tout sélectionner

function cacul_pourcentage($nombre,$total) { $resultat = ($nombre/$total) * 100; return round($resultat); // Arrondi la valeur }
Ok pour les "SELECT *", je modifirais mes requêtes ! :wink:

Eléphant du PHP | 259 Messages

14 mars 2007, 09:59

Je ne vois pas comment faire pour trier suivant le pourcentage... je cherche depuis hier.. masi aucune idée.. :?

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

14 mars 2007, 10:23

Excuse moi, je ne suis pas revenu te voir hier :oops:

Donc, si je comprend bien, tu fait une requête pour obtenir toutes les réponse puis, pour chaque réponse, une requete pour avoir le nombre total de vote et enfin une requête pour avoir le nombre de vote pour cette réponse, vrai ???

Tu seras d'accord avec moi que, pour toutes les réponses, le nombre total de vote sera le même ...
On peut donc dire que si tu ordonnes selon le volume de vote, tu auras un ordre identique au pourcentage ...

Ma solution consiste donc à remplacer la requête qui sélectionne la réponse par une requête qui fait une jointure entre les table REPONSE et VOTE, ce qui te permettra d'ordonner les résultats par le nombre de vote.

Par contre, pour t'aider plus précisément, il me faudrait la structure de tes table QUESTION, REPONSE et VOTE stp
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Eléphanteau du PHP | 21 Messages

14 mars 2007, 10:36

j'ai pas lu ton code, désolé, mais pourquoi tu ne mets pas ton résultat dans un tableau que tu classes ensuite?

Eléphant du PHP | 259 Messages

14 mars 2007, 11:17

Voici la structure de mes tables :

Question : id question, id sondage, titre question, methode (bouton radio, case a cocher..etc), position.

Réponse : id rep, id question, id sondage, intitule, position

Vote : id vote, id sondage, id question, id réponse, texte libre (lorque c'est du texte a sasir).

Oui je fait bien une requête pour obtenir toutes les réponses (dc les intitulé), puis je calcul le nombre total de vote pour une question ($nb_rep) et aprés une requête pour avoir le nombre de vote pour chaque réponse de la question.

Donc, oui le nombre total ($nb_rep) est le meme pour toutes les réponses d'une même question.

Oui je peux trier par le nombre de vote, ça marcherais aussi.

Donc je dois rajouter une jointure dasn cette requete :

Code : Tout sélectionner

$requete2 = "SELECT * FROM reponse WHERE id_sondage = '$id_sondage' AND id_question = '$id_question' ORDER BY position ";
Cela donnerait quelque chose comme ça :

Code : Tout sélectionner

$requete2 = "SELECT * FROM reponse, vote WHERE id_sondage = '$id_sondage' AND id_question = '$id_question' And reponse.id_reponse = vote.id_reponse";
Enfin là elle n'est pas bonne, ça me met une erreur

Code : Tout sélectionner

Erreur SQL : impossible d'effectuer la requête : SELECT * FROM reponse, vote WHERE id_sondage = '1' AND id_question = '3' And reponse.id_reponse = vote.id_reponse
Enfin, je ne vois pas trop si une jointure peut ordonné les résultats par le nombre de vote !

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

14 mars 2007, 11:32

OK, donc, je te conseille de remplacer la requête qui sélectionne les réponses par celle-là :
$sql = "	SELECT 
				r.id_sondage,
				r.id_question,
				r.id_reponse,
				COUNT(id_vote) as nb_vote
			FROM 
				reponse r,
				vote v
			WHERE 
				r.id_sondage = v.id_sondage			## Jointure entre les ...
				AND r.id_question = v.id_question	## ... tables REPONSE ...
				AND r.id_reponse = v.id_reponse		## ... et VOTE
				ANd id_sondage = '$id_sondage' 
				AND id_question = '$id_question'  
			GROUP BY			## Le GROUP BY permet de ne retourner qu'une seule occurence de
				r.id_sondage,	##>> chaque réponse, donc de regrouper les votes sous chaque
				r.id_question	##>> réponse
				r.id_reponse
			ORDER BY 				## Cet ORDER BY trie selon le volume de vote par réponse décroissant
				COUNT(id_vote) DESC	##>> donc, selon le pourcentage décroissant";
Je pense l'avoir assez commenté pour ne pas la ré-expliquer ici ;)

Ensuite, il ne te reste plus supprimer la requête qui remonte le nombre de vote par question et d'utiliser ce que cette requête remonte ;)
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Eléphant du PHP | 259 Messages

14 mars 2007, 11:51

Merci beaucoup, ça marche trés bien :wink:

je remet la requête, j'ai du modifier quelques trucs car il mettait erreur de syntaxe :
<?

$sql= "SELECT r.intitule, r.id_sondage, r.id_question,r.id_reponse,COUNT(id_vote) as nb_vote 
					FROM reponse r, vote v 
					WHERE r.id_sondage = v.id_sondage 
					AND r.id_question = v.id_question   
	                AND r.id_reponse = v.id_reponse       
	                ANd r.id_sondage = '$id_sondage'  
	                AND r.id_question = '$id_question'  
					GROUP BY  r.id_sondage,r.id_question, r.id_reponse 
					ORDER BY COUNT(id_vote) DESC";  
?>
Encore merci !

bye

(je met le sujet en résolu)

Eléphant du PHP | 259 Messages

15 mars 2007, 11:41

Il y a un petit soucis...

Avec la requête cela m'affiche bien les pourcentage dans l'ordre décroisant, mais lorsqu'il y a une réponse ou le pourcentage est de 0, il ne l'affiche pas..

Comment faire pour afficher les pourcentages qui sont a 0 ??

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

15 mars 2007, 12:42

Regarde du côté des jointures externes.

Un reponse LEFT JOIN vote devrai retourner toutes les réponses, même celles qui n'ont pas de votes.
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Eléphant du PHP | 259 Messages

15 mars 2007, 12:56

merci beaucoup, ça marche trés bien :wink:

Eléphant du PHP | 259 Messages

15 mars 2007, 22:07

Désolée, c'est encore moi...

Je testé mon programme chez moi (en local avec easy php) et il me met une erreur sur la requête :

Code : Tout sélectionner

Utilisation invalide de la clause GROUP
Je ne vois pas pourquoi ça ne marche pas..et surtout pourquoi ça marchait tout a l'heure sur un autre PC !!

Je remet la requête :
<?
		$requete2 = "SELECT r.intitule, r.id_sondage, r.id_question,r.id_reponse,COUNT(id_vote) as nb_vote 
					FROM reponse r LEFT JOIN vote v 
					ON (r.id_reponse = v.id_reponse AND r.id_question = v.id_question AND r.id_sondage = v.id_sondage)				
	                WHERE r.id_sondage = '$id_sondage' 
	                AND r.id_question = '$id_question'  
					GROUP BY  r.id_sondage,r.id_question, r.id_reponse 
					ORDER BY COUNT(id_vote) DESC"; 
?>

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

16 mars 2007, 00:06

Mis à part des opérateur de groupement (MAX, MIN, COUNT, SUM, ...), tout les champs qui sont dans le SELECT doivent être dans le GROUP BY ;)
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Eléphant du PHP | 259 Messages

16 mars 2007, 10:07

meme en mettant les meme champs dans le select et le group by, ça me met la même erreur.

J'ai modifié le group by, j'ai mis :

Code : Tout sélectionner

GROUP BY r.intitule, r.id_sondage, r.id_question,r.id_reponse
mais toujours la meme erreur :

Utilisation invalide de la clause GROUP
Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in .....

Voici le code :
<?
				$requete2 = "SELECT r.intitule, r.id_sondage, r.id_question,r.id_reponse,COUNT(id_vote) as nb_vote 
					FROM reponse r LEFT JOIN vote v 
					ON (r.id_reponse = v.id_reponse AND r.id_question = v.id_question AND r.id_sondage = v.id_sondage)				
	                WHERE r.id_sondage = '$id_sondage' 
	                AND r.id_question = '$id_question'  
					GROUP BY r.intitule, r.id_sondage, r.id_question,r.id_reponse
					ORDER BY COUNT(id_vote) DESC"; 
					
					
                    $resultat2 = mysql_query($requete2);
					if (!$resultat2) echo mysql_error();
					
                    $total = mysql_num_rows($resultat2); 
                    if ($total == 0) 
						{ 
						echo'<u><h1>Il n\'y a aucune réponse</u></h1>'; 
						}
						else if ($total > 0) 

?>
Je pense que la faute su mysql_num_rows vient de la requête...