Я не рекомендую делать это как запрос к базе данных. Набор результатов будет содержать строки, которые не имеют смысла, если вы не видите строки над ними - и это не способ SQL.
Я бы предложил сначала агрегировать и поместить затраты в одну строку :
select name, id, string_agg(cost, ', ') as costs
from t
group by name, id;
Если вы действительно настаиваете на этом наборе результатов, очень важно иметь order by
во внешнем запросе, потому что без order by
результаты может быть в любом порядке. Следовательно, я думаю, что лучшее решение:
select (case when seqnum = 1 then name end) as name,
(case when seqnum = 1 then id end) as id,
cost
from (select t.*, row_number() over (partition by name, id order by cost) as seqnum
from t
) t
order by name, id, seqnum