views:

466

answers:

3

I have one table, which has three fields and data.

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

I want to select the record which has highest value of Total for each Name, so my result should be like this:

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

I tried group by name order by total, but it give top most record of group by result. Can anyone guide me, please?

+2  A: 
select
  Name, Top, Total
from
  sometable
where
  Total = (select max(Total) from sometable i where i.Name = sometable.Name)

or

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
Tomalak
hi sir,thanks for your quick reply.i also created one query just now, and its giving me perfect result.here is my query select Name, Top, total from animals where total in(SELECT max(total) FROM `animals` group by name) group by namemy question is, which is more efficient, yours or mine when table contain 2 millions of data?thanks again for your reply.
Which is more efficient? Define proper indexes on your table and try it out. Apart from that, your `WHERE total in (...)` is wrong. You would quickly see this once you try with *actual* millions of records and not just a hand full.
Tomalak
The second query is likely to more efficient than the first because the first uses a correlated sub-query which might be executed many times instead of just once in the second version.
Jonathan Leffler
+1  A: 

You can try something like

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
astander
A: 

Or using an Exists clause, wich returns the only row that exists in both tables

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
)
Claudia
This will work, with the caveat about it being expensive on big tables with a naïve optimizer that does not manage to execute the correlated sub-query just once.
Jonathan Leffler
@Jonathan +1 solely for using the diacritical i in "naïve". :-)
Tomalak