Another variation on the previous suggestions. See what happens to all the other solutions when any of the roles is changed into for example 'R&D'. Plus, I don't like the replace()-approach to get rid of the last ','. I rather don't generate it if it's not needed instead of taking it off in an additional processing step:
SELECT
u1.UserID,
(
select case row_number() over (order by (select 1)) when 1 then '' else ', ' end
+ t.RoleName AS [text()]
from (
select row_number() over (order by min(u2.RoleAssignedDate)) as nr, u2.RoleName
from @UserRole u2
where u2.UserID = u1.UserID
group by u2.RoleName
) t
order by t.nr
for xml path(''), type
).value('.', 'nvarchar(max)') as Roles
from (
select
UserID
from @UserRole
group by
UserID
) u1
order by u1.UserID