Sélectionnez la valeur maximale de chaque groupe

87
Name    Value   AnotherColumn
-----------
Pump 1  8000.0  Something1
Pump 1  10000.0 Something2
Pump 1  10000.0 Something3
Pump 2  3043    Something4
Pump 2  4594    Something5
Pump 2  6165    Something6

Ma table ressemble à quelque chose comme ça. Je voudrais savoir comment sélectionner la valeur maximale pour chaque pompe.

select a.name, value from out_pumptable as a,
(select name, max(value) as value from out_pumptable where group by posnumber)g where and g.value = value

ce code fait le travail, mais j'obtiens deux entrées de la pompe 1 car elle a deux entrées avec la même valeur.

Wai Wong
la source

Réponses:

182
select name, max(value)
from out_pumptable
group by name
m.edmondson
la source
36
Mais cela ne fonctionnera pas sur Postgres ou tout autre SGBDR avec strict GROUP BY. Au sens strict, GROUP BYchaque colonne de votre SELECTdoit apparaître dans votre GROUP BYou être utilisée dans une fonction d'agrégation.
NickAb
4
Droite. «Fonctionne dans MySQL» dans ce contexte signifie essentiellement qu'il ne plante pas, pas qu'il renvoie nécessairement le résultat correct.
Craig
2
@Craig faux, cette requête fonctionne dans toutes les saveurs de rdbms et renvoie les données comme prévu, car l'OP n'était pas après avoir renvoyé l'enregistrement entier avec la valeur maximale par groupe, mais voulait la valeur maximale par pompe. La liste de sélection comporte 2 champs: nom et valeur. Le nom est dans la clause group by et la valeur est agrégée via max. Je ne vois aucune version de la réponse où il y aurait eu plus de champs dans la liste de sélection.
Shadow
3
@Craig ce n'était pas le comportement par défaut. Il a été modifié dans la version 5.7.5, il y a près de 3 ans. Mais encore une fois, vous manquez le point: le code de cette réponse est conforme au standard sql, donc le groupe par paramètre de mysql n'est pas pertinent.
Shadow
13
@NickAb Est-ce que je manque quelque chose? Chaque colonne est dans le groupe par ou dans une fonction d'agrégation
Rob
17
SELECT
  b.name,
  MAX(b.value) as MaxValue,
  MAX(b.Anothercolumn) as AnotherColumn
FROM out_pumptabl
INNER JOIN (SELECT 
              name,
              MAX(value) as MaxValue
            FROM out_pumptabl
            GROUP BY Name) a ON 
  a.name = b.name AND a.maxValue = b.value
GROUP BY b.Name

Notez que ce serait beaucoup plus facile si vous aviez une clé primaire. Voici un exemple

SELECT * FROM out_pumptabl c
WHERE PK in 
    (SELECT
      MAX(PK) as MaxPK
    FROM out_pumptabl b
    INNER JOIN (SELECT 
                  name,
                  MAX(value) as MaxValue
                FROM out_pumptabl
                GROUP BY Name) a ON 
      a.name = b.name AND a.maxValue = b.value) 
John Hartsock
la source
Ah, dang. J'ai rendu l'exemple trop simple. Il y a plus de colonnes dans le tableau, ce qui le rend un peu compliqué>. <
Wai Wong
S'il y a plus de colonnes, ajoutez-les simplement dans la sélection
m.edmondson
Pouvez-vous élaborer sur les colonnes. Par quoi essayez-vous de regrouper?
John Hartsock
@Wai Wrong Je vois que vous avez ajouté une autre colonne mais vous devez expliquer ce que vous voulez en faire? Voulez-vous renvoyer une valeur de cette colonne? Voulez-vous regrouper par nom et SomeOtherColumn?
John Hartsock
Ajout d'une autre colonne. Je veux obtenir la valeur maximale pour chaque pompe ainsi que les valeurs qui sont dans la ligne de la valeur maximale des autres colonnes. Suis-je trop déroutant?
Wai Wong
16
select name, value 
from( select name, value, ROW_NUMBER() OVER(PARTITION BY name ORDER BY value desc) as rn
from out_pumptable ) as a
where rn = 1
twk7890
la source
C'est le seul exemple qui fonctionne pour mon cas. J'ai plusieurs valeurs par «inscription». Ce dont j'ai besoin, c'est la dernière valeur pour chaque inscription, à gauche jointure externe. Commandé par id DESCle PARTITIONet enveloppé cette requête dans un LEFT OUTER JOIN as grades ON grades.enrollment_id = enrollment.idet fonctionne parfaitement.
lucasarruda
2
select Name, Value, AnotherColumn
from out_pumptable
where Value =
(
  select Max(Value)
  from out_pumptable as f where f.Name=out_pumptable.Name
)
group by Name, Value, AnotherColumn

Essayez comme ça, ça marche.

Lilit Galstyan
la source
1
select * from (select * from table order by value desc limit 999999999) v group by v.name
Umair Sheikh
la source
-3
SELECT DISTINCT (t1.ProdId), t1.Quantity FROM Dummy t1 INNER JOIN
       (SELECT ProdId, MAX(Quantity) as MaxQuantity FROM Dummy GROUP BY ProdId) t2
    ON t1.ProdId = t2.ProdId
   AND t1.Quantity = t2.MaxQuantity
 ORDER BY t1.ProdId

cela vous donnera l'idée.

Muhammad Jahanzeb
la source