これらのタイプの結果は、他のRDBMSのウィンドウ関数で処理するのが最適ですが、残念ながらMysqlにはウィンドウ関数がないため、ユーザー定義変数を使用して同じグループに属する行にランクを割り当てるソリューションがあります。
SELECT `id`, `category`, `names`
FROM (
SELECT *,
@r:= CASE WHEN @g = category THEN @r + 1 ELSE 1 END rownum,
@g:=category
FROM test
CROSS JOIN(SELECT @g:=NULL ,@r:=0) t
ORDER BY category,id desc
) c
WHERE c.rownum <=2
上記のクエリでは、カテゴリごとに2つの最近のレコード(idに基づく)が表示されます。where句を含むクエリの最後の部分を任意の数に変更して、グループごとにn個の結果を表示できます。たとえば、3つのレコードを表示してからWHERE c.rownum <= 3
など