Este tipo de resultados se manejan mejor con funciones de ventana en otros RDBMS, pero desafortunadamente Mysql no tiene ninguna función de ventana, por lo que, como alternativa, existe una solución para usar variables definidas por el usuario para asignar un rango a las filas que pertenecen al mismo grupo
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
La consulta anterior le dará 2 registros recientes (en función de la identificación) por categoría. Puede cambiar la última parte de la consulta con la cláusula where a cualquier número para mostrar n resultados por grupo, por ejemplo, para mostrar 3 registros y luego WHERE c.rownum <= 3
y así sucesivamente