MySQL SELECT n base de loggings en GROUP BY

Digamos que tengo loggings SQL:

 País |  Número
 Estados Unidos |  300
 Estados Unidos |  450
 Estados Unidos |  500
 Estados Unidos |  100
 Reino Unido |  300
 Reino Unido |  400
 Reino Unido |  1000

Y estoy haciendo algo como esto: SELECT * FROM table GROUP BY Country .
¿Qué sucede si deseo elegir mostrar el resultado con 2 numbers más grandes solo en cada país? ¿Cómo puedo archivar esto?

El resultado sería:

 País |  Número
 Estados Unidos |  450
 Estados Unidos |  500
 Reino Unido |  400
 Reino Unido |  1000

Data de muestra

 create table data (Country varchar(10), Number int); insert into data select 'USA' , 300 union all select 'USA' , 450 union all select 'USA' , 500 union all select 'USA' , 100 union all select 'FR' , 100 union all select 'FR' , 420 union all select 'UK' , 300 union all select 'UK' , 400 union all select 'UK' , 1000; 

La primera opción es un pseudo range que usa variables como The Scrum Meister, pero presentado aquí como un solo enunciado

 SELECT Country, Number FROM ( SELECT Number, @r := case when @c=country then @r+1 else 1 end rownum, @c := Country Country FROM (select @r :=0 , @c := '') x, data ORDER BY Country, Number DESC ) y WHERE rownum < 3; 

Si usa esto en una interfaz, y solo necesita 2 recuentos, puede usar este formulario que devuelve los recuentos en una list (columna única)

 SELECT Country, left(x,locate(',',concat(x,','),locate(',',x)+1)-1) Numbers FROM ( SELECT a.Country, Group_Concat(a.Number) x From ( select country, number from data order by country, number desc) a group by a.Country ) b 

El resultado es

 "Country";"Numbers" "FR";"420,100" "UK";"1000,400" "USA";"500,450" 

Si es posible que ocurran vínculos, esta variación de la 2ª forma elimina los vínculos y muestra los "2 principales numbers distintos por país", como loggings.

 SELECT distinct x.Country, x.Number From data x inner join ( SELECT Country, left(x,locate(',',concat(x,','),locate(',',x)+1)-1) Numbers FROM ( SELECT a.Country, Group_Concat(a.Number) x From ( select distinct country, number from data order by country, number desc) a group by a.Country ) b ) y on x.Country=y.Country and concat(',',y.Numbers,',') like concat('%,',x.Number,',%') order by x.Country, x.Number Desc 

Resultado

 "Country";"Number" "FR";"420" "FR";"100" "UK";"1000" "UK";"400" "USA";"500" "USA";"450" 

Como MySql no tiene una function RANK incorporada, la consulta puede ser lenta:

 SET @cRank = 0; SET @cCoutnry = ''; SELECT Country, Number FROM ( SELECT Number, @cRank := IF(@cCoutnry = Country, @cRank+1, 1) AS rank, @cCoutnry := Country Country FROM table ORDER BY Country, Number DESC ) rs WHERE rank < 3 

Vamos a nombrar su tabla TName, entonces la consulta sería.

 SELECT * FROM (SELECT ROW_NUMBER() OVER (PARTITION BY X.Country) AS RowNo, * FROM (SELECT Country, Name FROM TName ORDER BY Country, Number) X ) Y WHERE Y.RowNo <= 2