С функцией окна ROW_NUMBER()
:
select t.id, t.name, t.age, t.weight
from (
select *, row_number() over (partition by id order by weight desc) rn
from tablename
) t
where t.rn <= 3
order by t.id, t.weight desc
См. Демонстрацию .
Без оконных функций вы можете использовать коррелированный подзапрос в предложении WHERE
:
select t.id, t.name, t.age, t.weight
from tablename t
where (select count(*) from tablename where id = t.id and weight >= t.weight) <= 3
order by t.id, t.weight desc;
См. demo .
Результаты:
| id | name | age | weight |
| --- | ------ | --- | ------ |
| 1 | teste6 | 18 | 106 |
| 1 | teste5 | 18 | 105 |
| 1 | teste4 | 18 | 104 |
| 2 | teste2 | 18 | 96 |
| 2 | teste1 | 18 | 95 |
| 2 | teste9 | 18 | 94 |
| 3 | teste3 | 18 | 89 |
| 3 | teste3 | 18 | 88 |
| 3 | teste3 | 18 | 87 |