There's probably a simpler way, but this works:
with N as
(
select name, count(*) over (partition by name order by name) c from PersonPlace
),
Q as
(
select J.name, J.place, cast(J.place as varchar) place_name, J.c cnt, 1 c from
(select distinct(name) from PersonPlace) K
cross apply
(
select top 1 P.*, N.c from PersonPlace P
inner join N on N.name = P.name
where P.name = K.name
) J
union all
select P.name, P.place, cast(Q.place + ', ' + P.place as varchar), Q.cnt, Q.c + 1
from PersonPlace P
inner join Q on Q.name = P.name and Q.c + 1 <= cnt and P.place <> Q.place
)
select Q.name, Q.place_name from Q where Q.c = Q.cnt
Results:
name place_name
-------------- ----------------------
Steve Jones New York, Washington
Albert Smith Denver, Miami
Rextest Demo
If the People
and Places
are actually separate tables with their own keys, then we can simply quite a bit.