Кажется нелогичным, но вы можете удалить из общего табличного выражения (при определенных обстоятельствах). Итак, я бы сделал это так:
with cte as (
select *,
row_number() over (partition by userid, friendsid order by fid) as [rn]
from FriendsData
)
delete cte where [rn] <> 1
Это сохранит запись с самым низким значением индекса. Если вы хотите что-то еще, измените порядок по предложению в предложении over.
Если это вариант, наложите ограничение на уникальность таблицы, чтобы вам не приходилось это делать. Это не поможет спасти лодку, если у вас все еще есть утечка!