Problème sql (max selon critère)

Fermé
eric204044 Messages postés 33 Date d'inscription mercredi 30 juin 2010 Statut Membre Dernière intervention 15 septembre 2010 - 28 juil. 2010 à 13:58
eric204044 Messages postés 33 Date d'inscription mercredi 30 juin 2010 Statut Membre Dernière intervention 15 septembre 2010 - 1 août 2010 à 14:27
Bonjour à tous,
Voilà je galère un peu sur une requete alors si quelqu'un pouvait m'aider ça serait vraiment sympa.
Je vous explique mon problème, j'ai une table sql qui contient des identifiants d'image, ainsi que des identifiants de questions.
Je souhaiterais sélectionner pour chaque image(id_image),et pour chaque question(id_question),la réponse la plus fréquemment donnée et sa suivante.
Par exemple si dans ma table j'ai :
id_image id_question id_reponse nb_reponses(trouvé avec une requete sql utilisant un count)
1 3 5 10
1 3 6 9
1 3 4 8

Pour l'image 1,à la question 3,on a répondu 10 fois la réponse 5,9 fois la réponse 6 et 8 fois la réponse 4.
je souhaiterais pouvoir récupérer les 2 premières lignes (les réponses que l'on a répondu 10 et 9 fois)

Si quelqu'un a une idée,car là moi je ne vois pas du tout.
Merci d'avance
A voir également:

11 réponses

HostOfSeraphim Messages postés 6750 Date d'inscription jeudi 2 février 2006 Statut Contributeur Dernière intervention 31 juillet 2016 1 608
28 juil. 2010 à 16:01
Pour récupérer la première ligne de chaque question (à défaut de mieux, du moins pour l'instant) :

mysql> select * from t1;
+----------+-------------+------------+-------------+
| id_image | id_question | id_reponse | nb_reponses |
+----------+-------------+------------+-------------+
|        1 |           3 |          5 |          10 |
|        1 |           3 |          6 |           9 |
|        1 |           3 |          4 |           8 |
|        1 |           4 |          1 |          12 |
|        1 |           4 |          3 |           8 |
|        1 |           4 |          4 |           5 |
|        2 |           1 |          2 |          20 |
|        2 |           1 |          8 |          15 |
|        2 |           1 |          6 |          12 |
|        2 |           2 |          1 |          11 |
|        2 |           2 |          6 |           9 |
|        2 |           2 |          3 |           4 |
|        2 |           3 |          1 |           9 |
|        2 |           3 |          7 |          11 |
|        2 |           3 |          9 |          16 |
+----------+-------------+------------+-------------+
15 rows in set (0.00 sec)

mysql> select id_image, id_question, id_reponse, nb_reponses from (select * from t1 order by id_image, id_question, nb_reponses desc) as t1 group by id_image, id_question;
+----------+-------------+------------+-------------+
| id_image | id_question | id_reponse | nb_reponses |
+----------+-------------+------------+-------------+
|        1 |           3 |          5 |          10 |
|        1 |           4 |          1 |          12 |
|        2 |           1 |          2 |          20 |
|        2 |           2 |          1 |          11 |
|        2 |           3 |          9 |          16 |
+----------+-------------+------------+-------------+
5 rows in set (0.00 sec)

0
eric204044 Messages postés 33 Date d'inscription mercredi 30 juin 2010 Statut Membre Dernière intervention 15 septembre 2010
28 juil. 2010 à 16:09
J'obtiens aussi la meme chose que toi (je précise que nb_reponses n'est pas un champ de la table mais cette colonne est le résultat d'un count))
A partir de ce résultat, j'aimerais pouvoir récupérer les deux "nb_reponses" les plus élevés pour chaque id_reponse de chaque question et de chaque image/
Par exemple, si pour
l'image 1, pour la question 3 j'ai les réponses 8,9,10 et 11
id_image id_question id_reponse nd_reponses
1 3 8 12
1 3 9 10
1 3 10 5
1 3 11 2

j'aimerais pouvoir récupérer les deux premières lignes, et ça pour tous les id_images et pour chacune des questions existantes.
0
HostOfSeraphim Messages postés 6750 Date d'inscription jeudi 2 février 2006 Statut Contributeur Dernière intervention 31 juillet 2016 1 608
28 juil. 2010 à 16:31
T'aurais pu dire que tu avais déjà trouvé cette requête, ça m'aurait évité de chercher... ;-)
0
eric204044 Messages postés 33 Date d'inscription mercredi 30 juin 2010 Statut Membre Dernière intervention 15 septembre 2010
28 juil. 2010 à 16:42
désolé c'est vrai que je me suis mal exprimé au début
0
HostOfSeraphim Messages postés 6750 Date d'inscription jeudi 2 février 2006 Statut Contributeur Dernière intervention 31 juillet 2016 1 608
28 juil. 2010 à 16:48
Eventuellement tu peux contourner le problème.

Admettons que tu utilises PHP.

Tu fais une boucle qui parcourt la requête suivante :

mysql> select distinct id_image, id_question from t1;
+----------+-------------+
| id_image | id_question |
+----------+-------------+
|        1 |           3 |
|        1 |           4 |
|        2 |           1 |
|        2 |           2 |
|        2 |           3 |
+----------+-------------+
5 rows in set (0.01 sec)


Tu mets la valeur de id_image dans $i et la valeur de id_question dans $j.

Ensuite, tu construis la requête suivante :

$sql = "";
$sql = $sql . "(select * from t1 where id_image=" . $i . " and id_question=" . $j . " order by nb_reponses desc limit 2)";

Tant que tu n'es pas à la fin de ton tableau, tu rajoutes " UNION ".

Ensuite, tu n'as plus qu'à exécuter la requête, ce qui donne (sans le parcours de la table avec les variables) :

mysql> (select * from t1 where id_image=1 and id_question=3 order by nb_reponses desc limit 2)
    -> union
    -> (select * from t1 where id_image=1 and id_question=4 order by nb_reponses desc limit 2)
    -> union
    -> (select * from t1 where id_image=2 and id_question=1 order by nb_reponses desc limit 2)
    -> union
    -> (select * from t1 where id_image=2 and id_question=2 order by nb_reponses desc limit 2)
    -> union
    -> (select * from t1 where id_image=2 and id_question=3 order by nb_reponses desc limit 2)
    -> ;
+----------+-------------+------------+-------------+
| id_image | id_question | id_reponse | nb_reponses |
+----------+-------------+------------+-------------+
|        1 |           3 |          5 |          10 |
|        1 |           3 |          6 |           9 |
|        1 |           4 |          1 |          12 |
|        1 |           4 |          3 |           8 |
|        2 |           1 |          2 |          20 |
|        2 |           1 |          8 |          15 |
|        2 |           2 |          1 |          11 |
|        2 |           2 |          6 |           9 |
|        2 |           3 |          9 |          16 |
|        2 |           3 |          7 |          11 |
+----------+-------------+------------+-------------+
10 rows in set (0.00 sec)




C'est loin d'être parfait, mais bon...


0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
eric204044 Messages postés 33 Date d'inscription mercredi 30 juin 2010 Statut Membre Dernière intervention 15 septembre 2010
28 juil. 2010 à 16:55
en fait nb_reponses n'est pas une colonne il est utilisé avec count
voici ma requete de base :

select id_image,id_question,id_reponse,count(reponse) as nb_reponses
from ma_table
group by id_image,id_question,reponse

je veux bien essayer ta méthode,mais comment mettre le union à chaque fois??

ps:effectivement je travaille sous php,donc ça tombe bien :-)
0
HostOfSeraphim Messages postés 6750 Date d'inscription jeudi 2 février 2006 Statut Contributeur Dernière intervention 31 juillet 2016 1 608
Modifié par HostOfSeraphim le 28/07/2010 à 17:12
Essaye quelque chose de ce genre (je n'ai pas de quoi tester là) :

<?   
$q = "select distinct id_image, id_question from t1;";    
$r = mysql_query($q);   
$n = mysql_num_rows($r);   
$sql = "";   
$i = 1;   
while ($v = mysql_fetch_array($r))   
 {   
$sql = $sql . "(select * from t1 where id_image=" . $v["id_image"]; 
$sql = $sql . " and id_question=" . $v["id_question"];  
$sql = $sql . " order by nb_reponses desc limit 2)";    
if ($i < $n) { $sql = $sql . " UNION "; } else { $i++; }   
}   
echo "La requête à exécuter est : " . $sql;   
?>
0
eric204044 Messages postés 33 Date d'inscription mercredi 30 juin 2010 Statut Membre Dernière intervention 15 septembre 2010
28 juil. 2010 à 17:12
merci je vais tester ça et je te tiendrais au courant
0
eric204044 Messages postés 33 Date d'inscription mercredi 30 juin 2010 Statut Membre Dernière intervention 15 septembre 2010
28 juil. 2010 à 17:45
j'essaye depuis tout à l'heure,mais il y a une erreur,sans doute le dernier union,de plus,en exécutant la requete sous phpmyadmin(chacune des requetes séparément),je ne trouve pas le résultat attendu.
Le problème c'est que je récupère lesid_image et id_question,et que pour chacune des questions je veux les 2 réponses qui ont un count(reponse) les plus élevé
mais nb_reponses n'est pas une colonne,donc je ne comprends plus rien,si tu pouvais m'aider ça serait vraiment sympa de ta part.
0
HostOfSeraphim Messages postés 6750 Date d'inscription jeudi 2 février 2006 Statut Contributeur Dernière intervention 31 juillet 2016 1 608
28 juil. 2010 à 17:54
Je ne peux pas voir ça dans l'immédiat, par contre d'ici ce soir ou demain, oui.

Quel est le schéma exact de ta table ? Ca m'aiderait, notamment pour voir comment est fait le nb_reponses.
0
eric204044 Messages postés 33 Date d'inscription mercredi 30 juin 2010 Statut Membre Dernière intervention 15 septembre 2010
28 juil. 2010 à 17:57
j'ai réussi à trouver les deux premiers grace à cette requete :
select id_image,id_question,reponse,count(reponse) as nb_reponses
from ma_table
where id_image=6 and id_question=8
group by id_image,id_question,reponse
order by nb_reponses desc limit 2

Cependant il me reste le problème de l'union,je vais essayer de réfléchir encore un peu.
Merci pour ton aide,et si tu as une idée qui pourrait m'éclairer, elle serait la bienvenue :-)
A+
0
eric204044 Messages postés 33 Date d'inscription mercredi 30 juin 2010 Statut Membre Dernière intervention 15 septembre 2010
28 juil. 2010 à 18:12
voici le schéma de la table :
id id_image id_question reponse date

id est auto-incrémenté,il ne sert donc pas ici.
id_image est un entier, id_question est un entier,reponse est également un entier,et date est la date du jour.

voila ce que j'ai écris :
$req="select distinct id_image ,id_question
from ma_table
group by id_image,id_question";
$result = mysql_query($req)or die ('Erreur SQL !'.$req.'<br />'.mysql_error());

$n = mysql_num_rows($result);
echo "nb de lignes : ".$n."<br/>";
$sql = "";
$i = 1;
while ($row = mysql_fetch_array($result)) {
$sql = $sql . "(select id_image,id_question,reponse,count(reponse) as nb_reponses from ma_table
where id_image=" . $row["id_image"] . "
and id_question=" . $row["id_question"] . "
group by id_image,id_question,reponse
order by nb_reponses desc limit 2)";

if ($i < $n) { $sql = $sql . "UNION" ; }
else { $i++; }
}
echo "La requête à exécuter est : " . $sql."<br/>";
$result2= mysql_query($sql)or die ('Erreur SQL !'.$sql.'<br />'.mysql_error());
0
HostOfSeraphim Messages postés 6750 Date d'inscription jeudi 2 février 2006 Statut Contributeur Dernière intervention 31 juillet 2016 1 608
29 juil. 2010 à 10:52
Bonjour,



Avec ces éléments :

mysql> desc t1;
+-------------+--------+------+-----+---------+-------+
| Field       | Type   | Null | Key | Default | Extra |
+-------------+--------+------+-----+---------+-------+
| id_image    | int(2) | YES  |     | NULL    |       |
| id_question | int(2) | YES  |     | NULL    |       |
| id_reponse  | int(2) | YES  |     | NULL    |       |
| nb_reponses | int(2) | YES  |     | NULL    |       |
+-------------+--------+------+-----+---------+-------+
4 rows in set (0.11 sec)

mysql> select * from t1;
+----------+-------------+------------+-------------+
| id_image | id_question | id_reponse | nb_reponses |
+----------+-------------+------------+-------------+
|        1 |           3 |          5 |          10 |
|        1 |           3 |          6 |           9 |
|        1 |           3 |          4 |           8 |
|        1 |           4 |          1 |          12 |
|        1 |           4 |          3 |           8 |
|        1 |           4 |          4 |           5 |
|        2 |           1 |          2 |          20 |
|        2 |           1 |          8 |          15 |
|        2 |           1 |          6 |          12 |
|        2 |           2 |          1 |          11 |
|        2 |           2 |          6 |           9 |
|        2 |           2 |          3 |           4 |
|        2 |           3 |          1 |           9 |
|        2 |           3 |          7 |          11 |
|        2 |           3 |          9 |          16 |
+----------+-------------+------------+-------------+
15 rows in set (0.00 sec)




Le code PHP suivant fonctionne chez moi :

<?   
$q = "select distinct id_image, id_question from t1;";    
$r = mysql_query($q);   
$n = mysql_num_rows($r);   
$sql = "";   
$i = 1;   
while ($v = mysql_fetch_array($r))   
 {   
$sql = $sql . "(select * from t1 where id_image=" . $v["id_image"]; 
$sql = $sql . " and id_question=" . $v["id_question"];  
$sql = $sql . " order by nb_reponses desc limit 2)";    
if ($i < $n) { $sql = $sql . " UNION "; $i++; } else { $i++; }   
}   
echo "La requête à exécuter est : " . $sql;   
?>




Il me retourne la requête suivante :

(select * from t1 where id_image=1 and id_question=3 order by nb_reponses desc limit 2) 
UNION 
(select * from t1 where id_image=1 and id_question=4 order by nb_reponses desc limit 2) 
UNION 
(select * from t1 where id_image=2 and id_question=1 order by nb_reponses desc limit 2) 
UNION 
(select * from t1 where id_image=2 and id_question=2 order by nb_reponses desc limit 2) 
UNION 
(select * from t1 where id_image=2 and id_question=3 order by nb_reponses desc limit 2)




Qui donne, sur ma table :

mysql>  (select * from t1 where id_image=1 and id_question=3 order by nb_reponses desc limit 2) UNION (select * from t1 where id_image=1 and id_question=4 order by nb_reponses
 desc limit 2) UNION (select * from t1 where id_image=2 and id_question=1 order by nb_reponses desc limit 2) UNION (select * from t1 where id_image=2 and id_question=2 order b
y nb_reponses desc limit 2) UNION (select * from t1 where id_image=2 and id_question=3 order by nb_reponses desc limit 2);
+----------+-------------+------------+-------------+
| id_image | id_question | id_reponse | nb_reponses |
+----------+-------------+------------+-------------+
|        1 |           3 |          5 |          10 |
|        1 |           3 |          6 |           9 |
|        1 |           4 |          1 |          12 |
|        1 |           4 |          3 |           8 |
|        2 |           1 |          2 |          20 |
|        2 |           1 |          8 |          15 |
|        2 |           2 |          1 |          11 |
|        2 |           2 |          6 |           9 |
|        2 |           3 |          9 |          16 |
|        2 |           3 |          7 |          11 |
+----------+-------------+------------+-------------+
10 rows in set (0.05 sec)

0
eric204044 Messages postés 33 Date d'inscription mercredi 30 juin 2010 Statut Membre Dernière intervention 15 septembre 2010
1 août 2010 à 14:27
Merci pour ton aide, je vais essayer de faire fonctionner tout ça.
Merci encore pour avoir passé du temps à lire toutes mes questions :-)
0