Here is a more generic example using OLAP functions. This will get the first four pairs of phone type and phone number for each name. If someone has less than four, the remaining ones will be filled with NULL. It is obvious how you could expand this to more than four.
select * from (
select id,
min(id) over (partition by name) as first_id,
name,
phone_type as phone_type1,
phone_no as phone_no1,
lead(phone_type,1) over (partition by name order by id) as phone_type2,
lead(phone_no,1) over (partition by name order by id) as phone_type2,
lead(phone_type,2) over (partition by name order by id) as phone_type3,
lead(phone_no,2) over (partition by name order by id) as phone_type3,
lead(phone_type,3) over (partition by name order by id) as phone_type4,
lead(phone_no,3) over (partition by name order by id) as phone_type4
from table
) where id = first_id
The outer select guarantees that you only get one row per person. You need this because the result of an OLAP function (in this case min(id)
) can't be put directly into a where clause.