You can use the PIVOT function to get the result but you will also have to implement using a row_number() so you can convert multiple addresses per person into columns.
If you had a known number of addresses, then you would hard-code the query:
select id, name, address_1, address_2
from
(
select p.id, p.name, a.address,
'Address_'+cast(row_number() over(partition by p.id
order by a.ownerid) as varchar(10)) rn
from people p
inner join addresses a
on p.id = a.ownerid
) d
pivot
(
max(address)
for rn in (address_1, address_2)
) piv;
See SQL Fiddle with Demo.
But if your case, you will have an unknown number of addresses per person so you will want to use dynamic SQL and place it into a stored procedure to execute:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME('Address_'+d.rn)
from
(
select cast(row_number() over(partition by a.ownerid
order by a.ownerid) as varchar(10)) rn
from Addresses a
) d
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT id, name, ' + @cols + '
from
(
select p.id, p.name, a.address,
''Address_''+cast(row_number() over(partition by p.id
order by a.ownerid) as varchar(10)) rn
from people p
inner join addresses a
on p.id = a.ownerid
) d
pivot
(
max(address)
for rn in (' + @cols + ')
) p '
execute(@query);
See SQL Fiddle with Demo. These both give a result:
| ID | NAME | ADDRESS_1 | ADDRESS_2 | ADDRESS_3 |
----------------------------------------------------------------
| 1 | Bob | 123 Fake Street | 221 Other Street | (null) |
| 2 | Jim | 123 e main street | (null) | (null) |
| 3 | Tim | 489 North Drive | 56 June Street | 415 Lost |
DataTableand showing it in some grid control?