<p>The following is the simplest possible example, but any solution should be able to scale to the required n top results: </p>
<p>Given the following table, which contains columns for people, groups, and ages, how do you get the 2 oldest people in each group? (Ties within a group should not produce more results, but instead give the top 2 in alphabetical order) </p>
<pre>
-------- ------- -----
| Person | Group | Age |
-------- ------- -----
| Bob | 1 | 32 |
|Jill|1|34|
| Shawn | 1 | 42 |
| Jake | 2 | 29 |
| Paul | 2 | 36 |
| Laura | 2 | 39 |
-------- ------- -----
</pre>
<p>Desired result set: </p>
<pre>
-------- ------- -----
| Shawn | 1 | 42 |
|Jill|1|34|
| Laura | 2 | 39 |
| Paul | 2 | 36 |
-------- ------- -----
</pre>
<hr>
Got a good MySQL specific answer from @Bohemian: </p>
<pre class="brush:php;toolbar:false;">select *
from (select * from mytable order by `Group`, Age desc, Person) x
group by `Group`</pre>
<p>It would be nice to be able to build on this, but I can't see how. </p>
In other databases, you can use
ROW_NUMBER
to achieve this functionality. MySQL does not supportROW_NUMBER
, but you can simulate it using a variable:Online demo: sqlfiddle
EDIT I just noticed that bluefeet posted a very similar answer: Give him 1. But this answer has two small advantages:
So I'm leaving it in case it helps someone.
Here is one way to do it, using
UNION ALL
(see SQL Fiddle with demo). This works for two groups, if you have multiple groups you need to specify thegroup
number and add a query for eachgroup
:There are multiple ways to achieve this, please refer to this article to determine the best method for your situation:
http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/
edit:
This may also work for you, it generates a line number for each record. Using the example from the link above, it will only return records with row numbers less than or equal to 2:
SeeDemo