Выберите максимальное значение для каждой группы

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

Моя таблица выглядит примерно так. Я хотел бы знать, как выбрать максимальное значение для каждого насоса.

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

этот код выполняет свою работу, но я получаю две записи о насосе 1, поскольку в нем есть две записи с одинаковым значением.

Вай Вонг
источник

Ответы:

183
select name, max(value)
from out_pumptable
group by name
m.edmondson
источник
39
Но это не будет работать в Postgres или любой другой СУБД со строгим GROUP BY. Строго говоря, GROUP BYкаждый столбец в вашем SELECTдолжен быть либо в вашем, GROUP BYлибо использоваться в агрегатной функции.
NickAb 07
4
Правильно. «Работает в MySQL» в этом контексте в основном означает, что он не дает сбоев, но не обязательно возвращает правильный результат.
Крейг
2
@Craig ошибается, этот запрос работает во всех разновидностях rdbms и возвращает данные, как и ожидалось, поскольку OP не был после возврата всей записи с максимальным значением для группы, но хотел максимальное значение для каждого насоса. В списке выбора есть 2 поля: имя и значение. Имя находится в предложении group by, а значение агрегируется через max. Я не вижу ни одной версии ответа, в которой было бы больше полей в списке выбора.
Shadow
3
@Craig это было не поведение по умолчанию. Это было изменено в v5.7.5, почти 3 года назад. Но опять же, вы упускаете главное: код в этом ответе соответствует стандарту sql, поэтому группа mysql по настройке не имеет значения.
Shadow
13
@NickAb Я что-то упускаю? Каждый столбец находится либо в группе по, либо в функции агрегирования
Роб
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

Обратите внимание, что это было бы намного проще, если бы у вас был первичный ключ. Вот пример

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) 
Джон Хартсок
источник
Ах, черт. Я сделал пример слишком простым. В таблице больше столбцов, что немного усложняет ее>. <
Вай Вонг
Если есть еще столбцы, просто добавьте их в список
m.edmondson
Можете подробнее рассказать о столбцах. По чему вы пытаетесь сгруппировать?
Джон Хартсок,
@Wai Неправильно, я вижу, что вы добавили еще один столбец, но вам нужно объяснить, что вы хотите с ним делать? Вы хотите вернуть значение из этого столбца? Вы хотите сгруппировать по имени и SomeOtherColumn?
Джон Хартсок,
Добавлен еще один столбец. Я хочу получить максимальное значение для каждого насоса вместе со значениями, которые находятся в строке максимального значения из других столбцов. Я слишком запутался?
Вай Вонг,
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
источник
Это единственный пример, который работает в моем случае. У меня есть несколько значений для "зачисления". Мне нужно последнее значение для каждой регистрации, оставленное внешним присоединенным. Заказанный id DESCна PARTITIONи завернул этот запрос в LEFT OUTER JOIN as grades ON grades.enrollment_id = enrollment.idи отлично работает.
lucasarruda
3
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

Попробуйте вот так, работает.

Лилит Галстян
источник
1
select * from (select * from table order by value desc limit 999999999) v group by v.name
Умайр Шейх
источник
-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

это даст вам представление.

Мухаммад Джаханзеб
источник