Wybierz maksymalną wartość każdej grupy

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

Mój stół wygląda mniej więcej tak. Chciałbym wiedzieć, jak wybrać maksymalną wartość dla każdej pompy.

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

ten kod spełnia swoje zadanie, ale otrzymuję dwa wpisy pompy 1, ponieważ ma dwa wpisy o tej samej wartości.

Wai Wong
źródło

Odpowiedzi:

183
select name, max(value)
from out_pumptable
group by name
m.edmondson
źródło
39
Ale to nie zadziała na Postgresie ani żadnym innym RDBMS ze ścisłym GROUP BY. Ściśle mówiąc, GROUP BYkażda kolumna w twoim SELECTmusi albo występować w twoim, GROUP BYalbo być używana w funkcji agregującej.
NickAb
4
Dobrze. „Działa w MySQL” w tym kontekście w zasadzie oznacza, że ​​nie ulega awarii, niekoniecznie zwraca poprawny wynik.
Craig,
2
@Craig źle, to zapytanie działa we wszystkich odmianach rdbms i zwraca dane zgodnie z oczekiwaniami, ponieważ OP nie zwrócił całego rekordu z maksymalną wartością na grupę, ale chciał uzyskać maksymalną wartość na pompę. Lista wyboru zawiera 2 pola: nazwa i wartość. Nazwa znajduje się w klauzuli group by, a wartość jest agregowana za pośrednictwem max. Nie widzę żadnej wersji odpowiedzi, w której na liście wyboru byłoby więcej pól.
Shadow
3
@Craig to nie było zachowanie domyślne. Zostało to zmienione w wersji 5.7.5, prawie 3 lata temu. Ale znowu nie rozumiesz: kod w tej odpowiedzi jest zgodny ze standardem sql, dlatego ustawienie grupy mysql jest nieistotne.
Shadow
13
@NickAb Czy coś mi brakuje? Każda kolumna jest albo w grupie, albo w funkcji agregującej
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

Zauważ, że byłoby to znacznie łatwiejsze, gdybyś miał klucz podstawowy. Oto przykład

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
źródło
Ach, cholera. Uczyniłem przykład zbyt prostym. W tabeli jest więcej kolumn, co trochę komplikuje sprawę>. <
Wai Wong
Jeśli jest więcej kolumn, po prostu dodaj je do selekcji
m.edmondson
Czy możesz rozwinąć te kolumny. Według czego próbujesz grupować?
John Hartsock
@Wai Źle Widzę, że dodałeś kolejną kolumnę, ale musisz wyjaśnić, co chcesz z nią zrobić? Czy chcesz zwrócić wartość z tej kolumny? Czy chcesz grupować według nazwy i SomeOtherColumn?
John Hartsock
Dodano kolejną kolumnę. Chcę uzyskać maksymalną wartość dla każdej pompy wraz z wartościami, które znajdują się w wierszu wartości maksymalnej z innych kolumn. Czy robię się zbyt zagmatwany?
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
źródło
To jedyny przykład, który działa w moim przypadku. Mam wiele wartości na „rejestrację”. To, czego potrzebuję, to ostatnia wartość dla każdej rejestracji, lewy zewnętrzny połączony. Zamówione przez id DESCna PARTITIONi owinięty tej kwerendy w sposób LEFT OUTER JOIN as grades ON grades.enrollment_id = enrollment.idi działa idealnie.
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

Spróbuj w ten sposób, to działa.

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

to da ci pomysł.

Muhammad Jahanzeb
źródło