简体   繁体   中英

MySQL Group returns multiple results when aggregate function is equal

I am trying to obtain a list of results from a database table ('result'), however, each member may have submitted multiple results, and I wish to retrieve their best time.

The query below works (although I'm not sure if it is efficient), except in the case where there are multiple results from the same competitor with the same time scored. (eg competitor #2 scores time 32.15 seconds twice). In this situation I get two rows for this competitor, rather than the one I'd like.

SELECT result_id FROM ( 
    SELECT member_id,MIN(time) AS mintime FROM result 
        JOIN member_result ON result.id = member_result.result_id 
        WHERE event_id = ? 
        GROUP BY member_id ORDER BY mintime ) AS x 
JOIN result ON result.time = x.mintime
JOIN member_result ON member_result.result_id = result.id
AND member_result.member_id = x.member_id

Any suggestions to fix the issue would be greatly received.

EDIT: Structure of tables as requested;

member_result (TABLE)
 id int unsigned (10)
 result_id int unsigned (10)
 member_id int unsigned (10)
 club_id int unsigned (10)

result (TABLE)
 id int unsigned (10)
 time decimal (6)
 is50mPool BIT ()
 date date ()
 verified BIT ()
 verified_date timestamp ()
 verified_comment varchar (255)
 hasEmailed BIT ()
 enabled BIT ()
 event_id int unsigned (10

sample issue: result: id#1 for event#2, time 60 member_result: id#1, result_id 1, member_id 3 result: id#2 for event#2, time 60 member_result: id#2, result_id 2, member_id 3

I'd just like one row returned, with either result_id - currently both rows are returned as the min time is equal.

EDITED:

You can try to use MIN or MAX depending on which is more intresting you on the ID, and then there is only one row:

like:

SELECT result_id FROM ( 
    SELECT member_id, MIN(member_result.id) as member_resultID ,MIN(time) AS mintime FROM result 
        JOIN member_result ON result.id = member_result.result_id 
        WHERE event_id = 2 
        GROUP BY member_id ORDER BY mintime ) 
AS x 
JOIN result ON result.time = x.mintime
JOIN member_result ON member_result.result_id = result.id
AND member_result.id = x.member_resultID

This returns only the MIN time for the given event for the first user. (so only one row instead of two)

and here is an SqlFiddle for this.

SELECT Distinct result_id FROM ( 
SELECT member_id,MIN(time) AS mintime FROM result 
    JOIN member_result ON result.id = member_result.result_id 
    WHERE event_id = ? 
    GROUP BY member_id ) AS x 
JOIN result ON result.time = x.mintime
JOIN member_result ON member_result.result_id = result.id
AND member_result.member_id = x.member_id 

have you tried this?

Actually, this turned out to be as simple as grouping again on the outer query - something which didn't appear to work initially because of a LIMIT statement I had in place without an ORDER BY before the limit that because of the GROUP BY the query broke.

SELECT result_id FROM ( 
SELECT member_id,MIN(time) AS mintime FROM result 
    JOIN member_result ON result.id = member_result.result_id 
    WHERE event_id = ? 
    GROUP BY member_id ORDER BY mintime ) AS x 
JOIN result ON result.time = x.mintime
JOIN member_result ON member_result.result_id = result.id
AND member_result.member_id = x.member_id
GROUP BY member_result.member_id

Thanks to all those who contributed!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM