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.