この種のクエリは、「グループあたり最大の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回複製されます)。これは重複を返します。