Вам нужна row_number()
функция с условным агрегированием:
select id, max(case when cat = 'a' then value end) a,
max(case when cat = 'b' then value end) b,
max(case when cat = 'c' then value end) c
from (select t.*, row_number() over (partition by id, cat order by value) as seq
from table t
) t
group by id, seq;
Тем не менее, он не производит ваш фактический результат (он оставляет нулевое значение, когда у кота есть только одно значение по сравнению с другими кошками), но он даст представление о том, как это сделать.