MySQL selecting max record in group by

2019-03-19 04:42发布

问题:

I am trying to create a query in a table that has some 500,000 records and some 50 or 60 columns. What I need is to collate these records into groups and select the max record in each group.

To simplify the problem I have a table as follows

+----+-------------+----------+--------+
| id | external_id | group_id | mypath |
+----+-------------+----------+--------+
|  1 |        1003 |        1 | a      | 
|  2 |        1004 |        2 | b      | 
|  3 |        1005 |        2 | c      | 
+----+-------------+----------+--------+

The simple group by is as follows

select * from temp GROUP BY group_id

which returns

+----+-------------+----------+--------+
| id | external_id | group_id | mypath |
+----+-------------+----------+--------+
|  1 |        1003 |        1 | a      | 
|  2 |        1004 |        2 | b      | 
+----+-------------+----------+--------+

Nice but not what I want. What I want is the entire record for max enternal_id in each group. In other words

+----+-------------+----------+--------+
| id | external_id | group_id | mypath |
+----+-------------+----------+--------+
|  1 |        1003 |        1 | a      | 
|  3 |        1005 |        2 | c      | 
+----+-------------+----------+--------+

Somehow I am looking to put a max(external_id) statement in here to filter what is needed but so far all my investigation has failed. Some guidance would be appreciated. It is important that when returning the max(external_id) that the entire record is selected as the path column differs.

回答1:

Much info at http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/

This has always been an annoying issue in MySQL. There have been ways around it, such as concatenating several fields together (starting with external_id), and then selecting the MAX() of that, and then breaking it back apart.

I suggest you use a derived table. First table (t1) is derived from a simple query where you identify the MAX(external_id), then you join from that to get the rest of the data.

THIS IS ONLY IF external_id IS UNIQUE

SELECT 
   t1.group_id, some_table.id, some_table.mypath
FROM 
   (
      SELECT group_id, MAX(external_id) AS external_id
      FROM some_table
      GROUP BY group_id
   ) as t1
INNER JOIN 
   sometable ON t1.external_id = sometable.external_id
WHERE ...