[MySQL] La quête de la requête....

La quête de la requête.... [MySQL] - SQL/NoSQL - Programmation

Marsh Posté le 28-12-2004 à 09:40:08    

Désolé pour le titre pas terrible, mais je ne sais pas trop comment résumer ma question en une ligne ^-^
 
J'ai fait en php/mysql une petite appli de gestion de record à un jeu (neverball pour ne pas le citer). J'ai réussi à faire tout ce que je voulais, sauf une opération.
 
Résumons mon problème. Supposons la table de record suivante dont la structure est la suivante :
 

| nom  | collection | niveau | temps | pièces |


 
Pour un même niveau (de la même collection), il peut y avoir plusieurs entrées, pour plusieurs 'nom' différent, avec plusieurs 'temps' différents, etc... il n'y a pas que LE meilleur record, quoi.  
 
Actuellement, quand j'affiche ma table, j'affiche tous les records pour chaque niveau (avec éventuellement d'autres filtres, bref.) Je voudrais faire une option, qui n'affiche que LE meilleur record par niveau (meilleur temps, et meilleur nombre de pièces).
 
L'idéal en fait (c'est peut-être utopique) serait que j'arrive à utiliser les requêtes que je fais actuellement, et faire l'opération "ne garder que les meilleurs records" sur les résultats.
 
N'étant pas bon en sql, je ne sais pas construire la requête pour effectuer cette opération. De plus, comme ca tourne sur un serveur mysql 4.0.22, je n'ai pas de sous-requête... Je précise, même si je sais qu'une jointure peut remplacer.
 
Pour les curieux, l'appli en question en en ligne ici pour l'instant : http://shinobufan.free.fr/nevertable/
 
Si quelqu'un pouvait me donner une piste.. merci ;)


Message édité par shinobufan le 28-12-2004 à 09:40:31
Reply

Marsh Posté le 28-12-2004 à 09:40:08   

Reply

Marsh Posté le 28-12-2004 à 09:47:16    

SELECT MIN(temps) GROUP BY niveau ?


Message édité par e-deby le 28-12-2004 à 09:47:32

---------------
Pour les sudistes :)
Reply

Marsh Posté le 28-12-2004 à 10:06:51    

Oui ca me renvoit bien le meilleur temps pour chaque niveau, mais comment ensuite récupérer tous les champs du record en question ? C'est plus là mon problème ^-^

Reply

Marsh Posté le 28-12-2004 à 10:34:09    

SELECT MIN(temps), nom, collection, pièces GROUP BY niveau  
 
ca marche pas ca ?

Reply

Marsh Posté le 28-12-2004 à 11:02:22    

Ben en fait ca ne me donne pas le record avec le meilleur temps. Ca me donne un des record (le premier dans l'ordre d'apparition du SELECT), avec en face le MIN(time) qui lui est bien le temps correspondant au meilleur record. Mais les valeurs des champs ne correspondent pas à ce record.
 
exemple :
 


id | nom     | collection | niveau | temps | pieces
30 | multi1  | 0          | 5      | 2.4   | 10
31 | multi2  | 0          | 5      | 1.4   | 10
32 | multi3  | 0          | 5      | 1.4   | 12
33 | multi4  | 0          | 5      | 1.4   | 13
34 | multi5  | 0          | 5      | 1.2   | 13


 


SELECT MIN( temps ) , id, nom, collection, niveau GROUP BY collection,niveau


me donne :


MIN(temps) | id  | nom     | collection | niveau
1.2        | 30  | multi1  | 0          | 5


 
Or l'id 30 n'est pas le meilleur record ! mais 1.2 est bien le meilleur temps.
 
 :whistle:

Reply

Marsh Posté le 31-12-2004 à 10:04:07    

je n'ai toujours pas trouvé le moyen d'effectuer cette opération en MySQL, j'ai essayé des jointures tout ça, mais ca ne me donne jamais ce que je veux...  
 
J'ai donc fait le traitement en PHP, en gardant mes requêtes actuelles, et en ajoutant une option "afficher que les meilleurs record", qui entraine un traitement supplémentaire, qui consiste à sortir la liste des records avec un :  
 
SELECT MIN(temps),collection,niveau GROUP BY collection,niveau
 
puis au moment de l'affichage ,en php, je regarde si le record à afficher est le meilleur temps, si oui je l'affiche, si non je ne l'affiche pas. C'est moyen comme solution, non ? Enfin ca tourne et ce n'est pas si lourd que ça, mais je suis sur qu'on peut le faire directement en SQL !  :pfff:

Reply

Marsh Posté le 03-01-2005 à 11:55:07    

La requête :
 

Code :
  1. SELECT MIN( temps ) , id, nom, collection, niveau GROUP BY collection,niveau;


 
n'est pas acceptée par Oracle par exemple, car on ne peut pas, dans une requête group by, récupérer un 'id' précis, juste un MAX, MIN, COUNT, etc.
 
Donc en fait, par défaut, je pense que mySql ne te sors pas d'erreur car il applique le MIN à tous les champs sélectionnés. Soit en fait :
 

Code :
  1. SELECT MIN( temps ) , MIN(id), MIN(nom), MIN(collection), MIN(niveau) GROUP BY collection,niveau;


 
Donc en fait, pour avoir le résultat que tu veux il faudrait pouvoir faire des sous-requêtes.
(SELECT ...
 WHERE TEMPS = (SELECT MIN(TEMPS) ...))
 
En mySql, en général, on contourne les sous-requêtes en faisant des tables temporaires (où on insère le meilleurs temps pour chaque jeu, et on fait une jointure ensuite).
Ou alors, on dénormalise un peu en ajoutant un champ à la table dans laquelle on stoque une valeur qui dit si le score est le meilleur ou non pour le jeu (à gérer dans le coded PHP lors de l'insertion dans la table, donc).

Reply

Marsh Posté le 03-01-2005 à 13:04:31    

Code :
  1. select temps as resultat, id, nom, collection niveau from X group by  niveau having min(temps) = resultat


 
ca marche aps ca ?


Message édité par Sebastien le 03-01-2005 à 13:05:20
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed