I believe something like this is what you want. You might be able to do it without a sub-query by comparing the current name value to the lag value and null it out if it's the same.
select case when row_number = 1 then id end AS id, case when row_number = 1 then name end as name, phone.number from( select person.id, person.name, phone.number, row_number() partition by( phone.person_id order by phone.number ) as row_number from person join phone on person.id = phone.person_id ) AS sub order by name, row_number;