here is a set-based method that utilizies the @variable = column = expression syntax of an UPDATE statement to avoid the ugly cursor...--ddldrop table ordersdrop table personsgocreate table persons (pk varchar(10) primary key)create table orders ([order] varchar(10) primary key, person varchar(10) constraint fk references persons(pk))go--sample datainsert persons(pk)select 'PersonID1'union select 'PersonID2'union select 'PersonID3'goinsert orders(person,[order])select 'PersonID1','OrderID1'union select 'PersonID1','OrderID2'union select 'PersonID1','OrderID3'union select 'PersonID2','OrderID4'union select 'PersonID2','OrderID5'union select 'PersonID3','OrderID6'union select 'PersonID3','OrderID7'union select 'PersonID3','OrderID8'go--create a temp table to work withselect person, [order], space(8000) as listinto #workingtablefrom persons p inner join orders o on p.pk = o.personorder by person, [order]--some variablesdeclare @list varchar(8000), @lastperson varchar(10)select @list = '', @lastperson = ''--build the list column of the temp tableupdate #workingtableset @list = list = case when @lastperson <> person then person + ', ' + [order] else @list + ', ' + [order] end, @lastperson = person--return the csvselect max(list)from #workingtablegroup by persondrop table #workingtablego
<O>