この種のクエリは、「グループあたり最大のn」の意味で言い換えることができます。この場合、「グループ」あたりの上位10スコアを「foo」の値にする必要があります。
このリンク これは、この質問に見事に対処し、クエリを実行するのに意味のある方法から始めて、徐々に最適化します。
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;
すべてでこれを実行したい場合 fooのレベル (つまり、GROUP BY fooを実行することを想像してください )、where foo in ...は省略できます。 行。
基本的に、内部クエリ(SELECT foo, score FROM tablebar WHERE foo IN ('abc','def') ORDER BY foo, score DESC )fooを取得します およびscore テーブルから、最初にfooで並べ替えます その後、降順でスコアを付けます。
@num := ... すべての行を増やすだけで、fooの新しい値ごとに1にリセットされます。 。つまり、@num は単なる行番号/ランクです(内部クエリを単独で実行して、意味を確認してください)。
次に、外部クエリは、ランク/行番号が10以下の行を選択します。
注:
UNIONを使用した元のクエリ 重複を削除するため、foo='abc'の上位10スコアの場合 すべて100の場合、1行のみが返されます((foo,score) ペアは10回複製されます)。これは重複を返します。