Kueri semacam ini dapat dirumuskan ulang dalam arti "terbesar-n-per-grup", di mana Anda ingin 10 skor teratas per "grup" menjadi nilai 'foo'.
Saya sarankan Anda melihat tautan ini yang menangani pertanyaan ini dengan luar biasa, dimulai dengan cara yang masuk akal untuk melakukan kueri Anda dan mengoptimalkannya secara bertahap.
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;
Jika Anda ingin melakukan ini di semua tingkat foo
(yaitu bayangkan melakukan GROUP BY foo
), Anda dapat menghilangkan where foo in ...
baris.
Pada dasarnya kueri dalam (SELECT foo, score FROM tablebar WHERE foo IN ('abc','def') ORDER BY foo, score DESC
) mengambil foo
dan score
dari tabel, pesan dulu dengan foo
dan kemudian skor menurun.
@num := ...
hanya menambah setiap baris, menyetel ulang ke 1 untuk setiap nilai baru foo
. Yaitu, @num
hanyalah nomor/peringkat baris (coba jalankan kueri dalam sendiri untuk melihat apa yang saya maksud).
Kueri luar kemudian memilih baris dengan peringkat/nomor baris kurang dari atau sama dengan 10.
CATATAN:
Kueri asli Anda dengan UNION
menghapus duplikat, jadi jika 10 skor teratas untuk foo='abc'
semuanya 100 maka hanya satu baris yang akan dikembalikan (karena (foo,score)
pasangan direplikasi 10 kali). Yang ini akan mengembalikan duplikat.