Selecione o valor máximo de cada grupo

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

Minha mesa é mais ou menos assim. Gostaria de saber como selecionar o valor máximo para cada bomba.

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

esse código faz o trabalho, mas recebo duas entradas da Bomba 1, pois tem duas entradas com o mesmo valor.

Wai Wong
fonte

Respostas:

182
select name, max(value)
from out_pumptable
group by name
m.edmondson
fonte
36
Mas isso não funcionará no Postgres ou qualquer outro RDBMS com estrito GROUP BY. Estritamente, GROUP BYcada coluna em seu SELECTdeve aparecer em seu GROUP BYou ser usada em uma função agregada.
NickAb
4
Certo. "Funciona no MySQL" neste contexto basicamente significa que não trava, não que necessariamente retorna o resultado correto.
Craig,
2
@Craig errado, essa consulta funciona em todos os sabores de rdbms e retorna os dados conforme o esperado, já que o OP não estava depois de retornar o registro inteiro com o valor máximo por grupo, mas queria o valor máximo por bomba. A lista de seleção possui 2 campos: nome e valor. O nome está na cláusula group by e o valor é agregado por meio de no máx. Não consigo ver nenhuma versão da resposta em que houvesse mais campos na lista de seleção.
Shadow
3
@Craig não era o comportamento padrão. Foi alterado na v5.7.5, há quase 3 anos. Mas, novamente, você perdeu o ponto: o código nesta resposta está em conformidade com o padrão sql, portanto, a configuração group by mysql é irrelevante.
Shadow
13
@NickAb Estou perdendo alguma coisa? Cada coluna está no grupo por ou em uma função de agregação
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

Observe que isso seria muito mais fácil se você tivesse uma chave primária. Aqui está um exemplo

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
fonte
Ah, droga. Tornei o exemplo muito simples. Há mais colunas na tabela, o que a torna um pouco complicada>. <
Wai Wong
Se houver mais colunas, basta adicioná-las ao select
m.edmondson
Você pode elaborar sobre as colunas. O que você está tentando agrupar?
John Hartsock
@Wai Wrong Vejo que você adicionou outra coluna, mas precisa explicar o que deseja fazer com ela. Você deseja retornar um valor dessa coluna? Você deseja agrupar por nome e SomeOtherColumn?
John Hartsock
Adicionada outra coluna. Quero obter o valor máximo de cada bomba junto com os valores que estão na linha do valor máximo das outras colunas. Estou ficando muito confuso?
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
fonte
Este é o único exemplo que funciona para o meu caso. Tenho vários valores por 'inscrição'. O que eu preciso é o último valor para cada inscrição, left outer join. Ordenado por id DESCno PARTITIONe empacotado esta consulta em a LEFT OUTER JOIN as grades ON grades.enrollment_id = enrollment.idfunciona perfeitamente.
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

Tente assim, funciona.

Lilit Galstyan
fonte
1
select * from (select * from table order by value desc limit 999999999) v group by v.name
Umair Sheikh
fonte
-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

isso lhe dará uma ideia.

Muhammad Jahanzeb
fonte