[SQL] Prendre les enregistrements valeur max par catégorie (GROUP BY)

Prendre les enregistrements valeur max par catégorie (GROUP BY) [SQL] - SQL/NoSQL - Programmation

Marsh Posté le 06-08-2006 à 16:01:46    

Bonjour,
 
J'ai une liste d'enregistrements classés par catégorie (champ "cat" ).
J'ai pour chaque enregistrement un champ valeur (champ "val" ) et un champ nom (champ "nom" )
Exemple :
 
nom   cat   val
 
foo   cat1  10
bar   cat2  05
ter   cat1  07
pot   cat2  08
 
Je souhaite sélectionner les enregistrement qui on la valeur "val" maximale dans leur catégorie "cat".
 
Exemple :
 
nom   cat   val
 
foo   cat1  10
pot   cat2  08
 
Je suppose qu'il s'agit GROUP BY rusé mais je ne parviens pas à ce que je veux :(
 
Des idées ?
 
Merci !

Reply

Marsh Posté le 06-08-2006 à 16:01:46   

Reply

Marsh Posté le 06-08-2006 à 17:44:09    

select nom,cat,max(val) as val from ta_table group by cat

Reply

Marsh Posté le 06-08-2006 à 17:59:15    

SELECT nom,cat,val FROM tatable GROUP BY cat HAVING MAX(val)=val ?

Reply

Marsh Posté le 07-08-2006 à 12:23:48    

Merci pour ces deux réponses :)
 
satirik > Non ça me prend bien le maximum dans la catégorie, mais pas le nom correspondant à ce maximum :(
 
je@nb > Bizarre, la requête ne m'affiche pas toutes les catégories mais seulement quelques-unes ! je n'arrive pas à savoir le critère qui les fait s'afficher ou pas...
 
je continue à chercher !

Reply

Marsh Posté le 07-08-2006 à 12:41:06    

ceyquem, si tu es sûr que pour une cat donnée tu as un et un seul nom, alors tu peux tenter cette requête. Cependant, il existe d'autres manières bien plus propres et plus rapides, selon le SGBD.
 

SELECT Max(nom) AS nom, cat, Max(val) AS val
  FROM tatable
 GROUP BY cat


 
Je ne te la conseille pas vraiment, mais bon...
 
Tu peux sinon faire comme ceci qui est plus académique mais moins performant,
 

SELECT t1.nom, t1.cat, t2.val
  FROM tatable t1 RIGHT JOIN
           (SELECT cat, Max(val) AS val
              FROM tatable
             GROUP BY cat) ON t1.cat = t2.cat

 

Reply

Marsh Posté le 07-08-2006 à 18:24:10    

j'arrive pas trop à corriger les erreurs de la jointure :(
 
pour l'autre requête, il semble que ça marche mais là je suis perplexe sur le MAX(nom) ! :)
 
Merci pour ton aide :)

Reply

Marsh Posté le 07-08-2006 à 18:29:06    

correction : la requête bizarre avec Max(nom) ne marche pas, je n'ai pas un seul nom par catégorie !

Reply

Marsh Posté le 07-08-2006 à 18:31:30    

Un exemple peut-être plus parlant pour illustrer ce que je veux faire :
 
- une liste d'élèves, leur classe et leur moyenne générale (nom, classe, moyenne)
 
je veux sortir pour chaque classe l'élève qui a la meilleure moyenne (si y'a des égalités, pas grave, on en prend un des deux comme on veur).

Reply

Marsh Posté le 07-08-2006 à 18:34:17    

Tu peux fournir un set d'exemple ? un .sql ou un copier/collé ici ?

Reply

Marsh Posté le 07-08-2006 à 18:41:02    

sur la table suivante :
 

loic ce1 14
gero ce1 19
julie ce1 19
paul ce2 17
eric ce2 14
toto ce2 08
bob cm1 10
eva cm1 12
pat cm1 16
marc cm2 13
marie cm2 15
yves cm2 11


 
je veux récupérer :
 

julie ce1 19
paul ce2 17
pat cm1 16
marie cm2 15


 
ou bien :
 

gero ce1 19
paul ce2 17
pat cm1 16
marie cm2 15


 
 (car égalité entre gero et julie) :jap:


Message édité par ceyquem le 07-08-2006 à 18:41:36
Reply

Marsh Posté le 07-08-2006 à 18:41:02   

Reply

Marsh Posté le 07-08-2006 à 18:44:35    

SELECT t1.nom, t1.cat, t2.val
  FROM tatable t1 RIGHT JOIN
           (SELECT cat, Max(val) AS val
              FROM tatable
             GROUP BY cat) ON (t1.cat = t2.cat AND t1.val = t2.val)


 
Il manquait une condition dans la seconde requête postée.
Sinon, tu peux également faire comme suit.
 

SELECT t1.nom, t1.cat, t1.val
  FROM tatable t1
WHERE (cat, val) = (SELECT cat, Max(val) AS val
                              FROM tatable
                             GROUP BY cat)

Reply

Marsh Posté le 07-08-2006 à 19:32:44    

waw c'est vrai que c'est lourd en traitement (3.4 s pour 400 enregistrements) !

Reply

Marsh Posté le 07-08-2006 à 19:34:14    

tu utilise quoi comme SGBD ?

Reply

Marsh Posté le 07-08-2006 à 19:49:55    

mySQL.
 
J'essaie d'autres requêtes mais ça passe pas. Exemple :
 

SELECT A.nom, A.note, A.classe, MAX(B.note) AS maxnote, B.classe FROM eleves A, eleves B WHERE A.note=maxnote AND A.classe = B.classe GROUP BY A.nom, A.note, A.classe ORDER BY A.classe ASC;


Message édité par ceyquem le 07-08-2006 à 19:50:08
Reply

Marsh Posté le 14-08-2006 à 10:40:03    

je comprend pas le souci

Code :
  1. select nom,cat,max(val)
  2. from tatable
  3. group by cat


doit marcher pour ce que tu veux faire

Reply

Marsh Posté le 16-08-2006 à 18:00:20    

il me faut le nom de l'élève et pas seulement sa classe (erreur dans ma requête SQL plus haut), et la requête que tu me proposes ne permet pas de récupérer le nom de l'élève qui a eu la meilleure note...

Reply

Marsh Posté le 16-08-2006 à 18:56:23    

bah oui

Reply

Marsh Posté le 17-08-2006 à 15:56:08    

:sweat:
 


select t1.nom, t1.val, t1.cat
from latable t1
where t1.val = (select max(t2.val) from latable t2 where t2.cat = t1.cat)

Reply

Marsh Posté le 03-02-2014 à 12:04:13    

merci pour ton aide Arjuna


Message édité par wardan le 03-02-2014 à 12:05:30
Reply

Marsh Posté le 03-02-2014 à 15:50:00    

IL Y A AUSSI UN AUTRE SOLUTION CA MARCHE BIEN.
 
Exemple de table livre :
id categorie date livre pages
1 | 10 | 04/03/2009 | livre A | 399
2 | 11 | 04/03/2009 | livre B | 244
5 | 12 | 04/03/2009 | livre C | 555
3 | 10 | 03/03/2009 | livre D | 300
4 | 11 | 03/03/2009 | livre E | 200
6 | 12 | 03/03/2009 | livre F | 500
1 | 10 | 04/03/2009 | livre A | 399
2 | 11 | 04/03/2009 | livre B | 244
5 | 12 | 04/03/2009 | livre C | 555
 
On souhaite récupérer le livre ayant la date la plus récente par catégorie pour obtenir le résultat suivant :
id categorie date livre pages
1 | 10 | 04/03/2009 | livre A | 399
2 | 11 | 04/03/2009 | livre B | 244
5 | 12 | 04/03/2009 | livre C | 555
 
SELECT l.*
FROM livre l
INNER JOIN
(
SELECT categorie, MAX(date) AS maxDate
FROM livre
GROUP BY categorie
) groupel ON l.categorie = groupel.categorie AND l.date = groupel.maxDate


Message édité par wardan le 03-02-2014 à 15:53:21
Reply

Sujets relatifs:

Leave a Replay

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