简体   繁体   中英

Collating all of the top 2 results of a query

I have a table of people, their favorite fruit, and the city they live in:

id          city          fruit           name
1           New York      Apples          Jim
2           New York      Bananas         Nancy
3           New York      Pears           Dwayne
4           New York      Apples          Edgar
5           New York      Apples          Ali
6           London        Bananas         John
7           London        Apples          Sara
8           London        Pears           Michelle
9           London        Apples          Don
10          London        Apples          Martin
11          Sydney        Bananas         Mike
12          Sydney        Apples          Toyah
13          Sydney        Apples          Craig
14          Sydney        Apples          Sheila
15          Sydney        Apples          Endo

I need to return the names of just two people per city, in ascending ID order , who like apples. In other words, the result I'm looking for is:

id          city          fruit           name
1           New York      Apples          Jim
4           New York      Apples          Edgar
7           London        Apples          Sara
9           London        Apples          Don
12          Sydney        Apples          Toyah
13          Sydney        Apples          Craig

ie to ignore all the other people who like apples in a particular city, as they have a higher ID number than the two other people who live in the city.

I can obviously get the top 2 results if searching by a particular city, but I'm struggling to then 'skip' to the next city once the top 2 are found... I'm lost in a world of multiple joins and FIND_IN_SETs here :-)

Thanks in advance

This question is a bit tricky, because you want the top two records per group in a query. If you only wanted the top record, we could of course use the MAX() function along with GROUP BY . In other databases, we could use the ROW_NUMBER() function here, but since MySQL does not have this capability built in, we can emulate it using a session variable.

SET @row_number = 0;
SET @city = NULL;

SELECT t.id, t.city, t.fruit, t.name
FROM
(
    SELECT @row_number:=CASE WHEN @city = city
                             THEN @row_number + 1 ELSE 1 END AS rn,
           id,
           @city:=city AS city,
           fruit,
           name
    FROM yourTable
    WHERE fruit = 'Apples'
    ORDER BY city, id
) t
WHERE t.rn <= 2

Demo here:

Rextester

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