Вы можете попробовать что-то вроде этого.
select name,age from
(select name,age,row_number() over (partition by age_group order by name desc) as rn
from (select name,age ,case when age between 16 and 25 then 20 when age between 26 and 35 then 30 when age between 36 and 45 then 40 else 0 end as "age_group" from table) t1 where age_group != 0) t2
where rn <=3
group by name,age
Я разделил возраст по возрастным группам ie 16 - 25 - 20, 26-35 - 30 и так далее. Используемый раздел по age_group и заданный каждой группе разными номерами. В этом случае, если в возрастной группе 20 лет есть 4 записи, то при использовании разбиения по выражению будет дано 1,2,3,4 строки, а для 30 - 3 записи - 1,2,3. И наконец фильтрация строк, имеющих более 3 строк для каждой группы.