# 获取每组分组结果的前n个logging

``` + -------- + ------- + ----- +
| 人|  Group | 年龄|
+ -------- + ------- + ----- +
|  Bob |  1 |  32 |
| 吉尔|  1 |  34 |
|  Shawn |  1 |  42 |
| 杰克|  2 |  29 |
| 保罗|  2 |  36 |
| 劳拉|  2 |  39 |
+ -------- + ------- + ----- +
```

``` + -------- + ------- + ----- +
|  Shawn |  1 |  42 |
| 吉尔|  1 |  34 |
| 劳拉|  2 |  39 |
| 保罗|  2 |  36 |
+ -------- + ------- + ----- +
```

``select * from (select * from mytable order by `Group`, Age desc, Person) x group by `Group`` `

` `( select * from mytable where `group` = 1 order by age desc LIMIT 2 ) UNION ALL ( select * from mytable where `group` = 2 order by age desc LIMIT 2 )` `

` `select person, `group`, age from ( select person, `group`, age, (@num:=if(@group = `group`, @num +1, if(@group := `group`, 1, 1))) row_number from test t CROSS JOIN (select @num:=0, @group:=null) c order by `Group`, Age desc, person ) as x where x.row_number <= 2;` `

` `SELECT person, groupname, age FROM ( SELECT person, groupname, age, @rn := IF(@prev = groupname, @rn + 1, 1) AS rn, @prev := groupname FROM mytable JOIN (SELECT @prev := NULL, @rn := 0) AS vars ORDER BY groupname, age DESC, person ) AS T1 WHERE rn <= 2` `

1. 它是一个单一的查询。 variables在SELECT语句内被初始化。
2. 它按照问题中的描述处理关系（按字母顺序排列）。

` `CREATE TABLE mytable (person, groupname, age); INSERT INTO mytable VALUES('Bob',1,32); INSERT INTO mytable VALUES('Jill',1,34); INSERT INTO mytable VALUES('Shawn',1,42); INSERT INTO mytable VALUES('Jake',2,29); INSERT INTO mytable VALUES('Paul',2,36); INSERT INTO mytable VALUES('Laura',2,39); SELECT a.* FROM mytable AS a LEFT JOIN mytable AS a2 ON a.groupname = a2.groupname AND a.age <= a2.age GROUP BY a.person HAVING COUNT(*) <= 2 ORDER BY a.groupname, a.age DESC;` `

` `a.person a.groupname a.age ---------- ----------- ---------- Shawn 1 42 Jill 1 34 Laura 2 39 Paul 2 36` `

` `.headers on .mode column CREATE TABLE foo (person, groupname, age); INSERT INTO foo VALUES('Paul',2,36); INSERT INTO foo VALUES('Laura',2,39); INSERT INTO foo VALUES('Joe',2,36); INSERT INTO foo VALUES('Bob',1,32); INSERT INTO foo VALUES('Jill',1,34); INSERT INTO foo VALUES('Shawn',1,42); INSERT INTO foo VALUES('Jake',2,29); INSERT INTO foo VALUES('James',2,15); INSERT INTO foo VALUES('Fred',1,12); INSERT INTO foo VALUES('Chuck',3,112); SELECT a.person, a.groupname, a.age FROM foo AS a WHERE a.age >= (SELECT MIN(b.age) FROM foo AS b WHERE (SELECT COUNT(*) FROM foo AS c WHERE c.groupname = b.groupname AND c.age >= b.age) <= 2 GROUP BY b.groupname) ORDER BY a.groupname ASC, a.age DESC;` `

` `person groupname age ---------- ---------- ---------- Shawn 1 42 Jill 1 34 Laura 2 39 Paul 2 36 Joe 2 36 Chuck 3 112` `

` `SELECT a.person, a.group, a.age FROM person AS a WHERE (SELECT COUNT(*) FROM person AS b WHERE b.group = a.group AND b.age >= a.age) <= 2 ORDER BY a.group ASC, a.age DESC` `

DEMO

` `SELECT p.Person, p.`Group`, p.Age FROM people p INNER JOIN ( SELECT MAX(Age) AS Age, `Group` FROM people GROUP BY `Group` UNION SELECT MAX(p3.Age) AS Age, p3.`Group` FROM people p3 INNER JOIN (SELECT MAX(Age) AS Age, `Group` FROM people GROUP BY `Group`) p4 ON p3.Age < p4.Age AND p3.`Group` = p4.`Group` GROUP BY `Group` ) p2 ON p.Age = p2.Age AND p.`Group` = p2.`Group` ORDER BY `Group`, Age DESC, Person;` `

SQL小提琴： http ://sqlfiddle.com/#!2/cdbb6/15

` `SELECT province, n, city, population FROM ( SELECT @prev := '', @n := 0 ) init JOIN ( SELECT @n := if(province != @prev, 1, @n + 1) AS n, @prev := province, province, city, population FROM Canada ORDER BY province ASC, population DESC ) x WHERE n <= 3 ORDER BY province, n;` `

` `+---------------------------+------+------------------+------------+ | province | n | city | population | +---------------------------+------+------------------+------------+ | Alberta | 1 | Calgary | 968475 | | Alberta | 2 | Edmonton | 822319 | | Alberta | 3 | Red Deer | 73595 | | British Columbia | 1 | Vancouver | 1837970 | | British Columbia | 2 | Victoria | 289625 | | British Columbia | 3 | Abbotsford | 151685 | | Manitoba | 1 | ...` `

` `select Person,[group],age from ( select * ,row_number() over(partition by [group] order by age desc) rn from mytable ) t where rn <= 2` `