Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

MySQL seleciona os principais registros X para cada indivíduo na tabela


Esse tipo de consulta pode ser reformulado no sentido de "maior n-por-grupo", onde você deseja que as 10 principais pontuações por "grupo" sejam valores de 'foo'.

Sugiro que você dê uma olhada em este link que trata essa questão maravilhosamente, começando com uma forma que faça sentido para realizar sua consulta e gradualmente otimizando-a.
set @num := 0, @foo := '';
select foo, score
from (
   select foo, score,
      @num := if(@foo = foo, @num + 1, 1) as row_number,
      @foo := foo as dummy
  from tablebar
  where foo IN ('abc','def')
  order by foo, score DESC     
) as x where x.row_number <= 10;

Se você quiser fazer isso em todos níveis de foo (ou seja, imagine fazer um GROUP BY foo ), você pode omitir o where foo in ... linha.

Basicamente a consulta interna (SELECT foo, score FROM tablebar WHERE foo IN ('abc','def') ORDER BY foo, score DESC ) pega foo e score da tabela, ordenando primeiro por foo e, em seguida, pontuação descendente.

O @num := ... apenas aumenta cada linha, redefinindo para 1 para cada novo valor de foo . Ou seja, @num é apenas um número/classificação de linha (tente executar a consulta interna por conta própria para ver o que quero dizer).

A consulta externa seleciona as linhas em que o número de classificação/linha é menor ou igual a 10.

NOTA:

Sua consulta original com UNION remove duplicatas, portanto, se as 10 melhores pontuações para foo='abc' são todos 100, então apenas uma linha será retornada (já que o (foo,score) par é replicado 10 vezes). Este retornará duplicatas.