2010-04-17 5 views
20

Mögliche Duplizieren:
Retrieving the last record in each groupSQL: Finden Sie die max Datensatz pro Gruppe

ich eine Tabelle haben, die drei Felder und Daten hat.

 
Name , Top , Total 
cat , 1 , 10 
dog , 2 ,  7 
cat , 3 , 20 
horse , 4 ,  4 
cat , 5 , 10 
dog , 6 ,  9 

Ich mag den Datensatz wählen, den höchsten Wert von Total für jeden Name hat, so mein Ergebnis so sein sollte:

 
Name , Top , Total 
cat , 3 , 20 
horse , 4 ,  4 
Dog , 6 ,  9 

I-Gruppe von insgesamt namentlich um versucht, aber es geben die meisten Datensätze der Gruppe nach Ergebnis. Kann mir bitte jemand helfen?

+3

existiert frage mich, wie viele Duplikate es für diese Abfrage gibt - sicherlich viele m Erz als nur eins. Sehen Sie sich die 60+ Fragen an, die mit "Größte-N-pro-Gruppe" markiert sind (für die Fälle n = 1). –

+0

@ Jonathan: Dies ist die "ewig Frage" im Bereich der Anfänger SQL-Fragen. Es gibt jeden Tag einen frischen auf SO. – Tomalak

Antwort

27
select 
    Name, Top, Total 
from 
    sometable 
where 
    Total = (select max(Total) from sometable i where i.Name = sometable.Name) 

oder

select 
    Name, Top, Total 
from 
    sometable 
    inner join (
    select max(Total) Total, Name 
    from sometable 
    group by Name 
) as max on max.Name = sometable.Name and max.Total = sometable.Total 
+0

hallo sir, danke für ihre schnelle antwort. Ich habe auch gerade eine Abfrage erstellt, und es gibt mir ein perfektes Ergebnis. hier ist meine Abfrage wählen Sie Name, Top, insgesamt von Tieren, bei denen insgesamt in (SELECT max (gesamt) FROM 'animals' Gruppe mit Namen) Gruppe namentlich meine Frage ist, was effizienter ist, Ihre eigenen oder meins, wenn die Tabelle 2 Millionen Daten enthält? Nochmals vielen Dank für Ihre Antwort. – user319088

+0

Was ist effizienter? Definieren Sie geeignete Indizes für Ihre Tabelle und probieren Sie sie aus. Abgesehen davon ist dein 'WHERE total in (...)' falsch. Sie würden dies schnell sehen, sobald Sie mit * tatsächlichen * Millionen von Datensätzen und nicht nur mit einer vollen Hand versuchen. – Tomalak

+2

Die zweite Abfrage ist wahrscheinlich effizienter als die erste Abfrage, da die erste Abfrage eine korrelierte Unterabfrage verwendet, die in der zweiten Version möglicherweise mehrmals statt nur einmal ausgeführt wird. –

5

Sie können wie etwas versuchen

SELECT s.* 
FROM sometable s INNER JOIN 
     (
      SELECT Name, 
        MAX(Total) MTotal 
      FROM sometable 
      GROUP BY Name 
     ) sMax ON s.Name = sMax.Name 
       AND s.Total = sMax.MTotal 
0

oder über eine EXISTS-Klausel, wich zurück, die einzige Zeile, die ich in beiden Tabellen

SELECT * from sometable T 
where exists 
(select 1 
from (SELECT nombre, max(total) as total FROM sometable TT 
    GROUP by nombre) TT 
where T.name=TT.name 
and T.total=TT.total 
) 
+1

Dies funktioniert, mit dem Vorbehalt, dass es auf großen Tabellen teuer ist, mit einem naiven Optimierer, der es nicht schafft, die korrelierte Unterabfrage nur einmal auszuführen. –

+1

@ Jonathan +1 nur für die Verwendung der diakritischen i in "naiv". :-) – Tomalak