you can use Stuff()
to concatenate values into single cell
Here is an example:
create table #temp (
firstname varchar(255),
surname varchar(255),
[role] varchar(255),
[subject] varchar(255)
)
insert into #temp
values ('Jane', 'Smith', 'Maths Teacher', 'Math'),
('Jane', 'Smith', 'Maths Teacher', 'Physics'),
('Jane', 'Smith', 'Maths Teacher', 'Tutorial'),
('Jane', 'Smith', 'Physics Teacher', 'Math'),
('Jane', 'Smith', 'Physics Teacher', 'Physics'),
('Jane', 'Smith', 'Physics Teacher', 'Tutorial'),
('Kate', 'Smith', 'Maths Teacher', 'Math1'),
('Kate', 'Smith', 'Maths Teacher', 'Physics'),
('Kate', 'Smith', 'Maths Teacher', 'Tutoria'),
('Kate', 'Smith', 'Physics Teacher', 'Math'),
('Kate', 'Smith', 'Physics Teacher', 'Physics'),
('Kate', 'Smith', 'Physics Teacher', 'Tutorial')
select * from #temp
select distinct firstname,surname, STUFF( (SELECT distinct ',' + [role]
FROM [#temp] t1
where t1.firstname = t2.firstname and t1.surname = t2.surname
FOR XML PATH('')),
1, 1, ''),
STUFF( (SELECT distinct ',' + [subject]
FROM #temp t1
where t1.firstname = t2.firstname and t1.surname = t2.surname
FOR XML PATH('')),
1, 1, '') as [subject]
from #temp t2
drop table #temp
Another way this could be achive by using Cross APPLY
create table #temp (
firstname varchar(255),
surname varchar(255),
[role] varchar(255),
[subject] varchar(255)
)
insert into #temp
values ('Jane', 'Smith', 'Maths Teacher', 'Math'),
('Jane', 'Smith', 'Maths Teacher', 'Physics'),
('Jane', 'Smith', 'Maths Teacher', 'Tutorial'),
('Jane', 'Smith', 'Physics Teacher', 'Math'),
('Jane', 'Smith', 'Physics Teacher', 'Physics'),
('Jane', 'Smith', 'Physics Teacher', 'Tutorial'),
('Kate', 'Smith', 'Maths Teacher', 'Math1'),
('Kate', 'Smith', 'Maths Teacher', 'Physics'),
('Kate', 'Smith', 'Maths Teacher', 'Tutoria'),
('Kate', 'Smith', 'Physics Teacher', 'Math'),
('Kate', 'Smith', 'Physics Teacher', 'Physics'),
('Kate', 'Smith', 'Physics Teacher', 'Tutorial')
select distinct firstname,surname,rol.[role], sub.subject
from #temp t2
CROSS APPLY (SELECT convert(varchar(20), [role]) + ','
FROM #temp t1
where t1.firstname = t2.firstname and t1.surname = t2.surname
GROUP BY firstname,surname,[role]
FOR XML PATH('')) rol([role])
CROSS APPLY (SELECT convert(varchar(20), [subject]) +','
FROM #temp t1
where t1.firstname = t2.firstname and t1.surname = t2.surname
GROUP BY firstname,surname,[subject]
FOR XML PATH('')) sub([subject])
drop table #temp