Mysql
 sql >> Database >  >> RDS >> Mysql

MySQL seleziona i primi X record per ogni individuo nella tabella

Questo tipo di query può essere riformulato nel senso di "più grande n-per-gruppo", dove vuoi che i primi 10 punteggi per "gruppo" siano valori di "pippo".

Ti suggerisco di dare un'occhiata a questo collegamento che affronta meravigliosamente questa domanda, iniziando con un modo sensato per eseguire la tua query e ottimizzandola gradualmente.

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 desideri eseguire questa operazione su tutti livelli di foo (cioè immagina di fare un GROUP BY foo ), puoi omettere where foo in ... linea.

Fondamentalmente la query interna (SELECT foo, score FROM tablebar WHERE foo IN ('abc','def') ORDER BY foo, score DESC ) prende foo e score dalla tabella, ordinando prima per foo e poi punteggio decrescente.

Il @num := ... aumenta semplicemente ogni riga, reimpostando a 1 per ogni nuovo valore di foo . Cioè, @num è solo un numero di riga/grado (prova a eseguire la query interna da sola per vedere cosa intendo).

La query esterna seleziona quindi le righe in cui il numero di rango/riga è minore o uguale a 10.

NOTA:

La tua richiesta originale con UNION rimuove i duplicati, quindi se i primi 10 punteggi per foo='abc' sono tutti 100, verrà restituita solo una riga (poiché il (foo,score) la coppia viene replicata 10 volte). Questo restituirà duplicati.