Sample data set:
select 'Report1' as reportID,'Browser' as RoleID, 'YChen' as User2
into #tbl
UNION
select 'Report1' as reportID,'Browser' as RoleID,'AChen' as User2
UNION
select 'Report1' as reportID,'Browser' as RoleID,'BChen' as User2
UNION
select 'Report2' as reportID,'Browser' as RoleID,'YChen' as User2
UNION
select 'Report2' as reportID,'Browser' as RoleID,'XChen' as User2
UNION
select 'Report2' as reportID,'Browser' as RoleID,'BChen' as User2
UNION
select 'Report1' as reportID,'Writer' as RoleID,'YChen' as User2
UNION
select 'Report1' as reportID,'Writer' as RoleID,'XChen' as User2
reportIDRoleIDUser2
Report1BrowserAChen
Report1BrowserBChen
Report1BrowserYChen
Report1WriterXChen
Report1WriterYChen
Report2BrowserBChen
Report2BrowserXChen
Report2BrowserYChen
~~~
Desired output:
reportIDroleIDlist
Report1BrowserAChen, BChen, YChen
Report1WriterXChen, YChen
Report2BrowserBChen, XChen, YChen
~~~
CTE method used (takes a long time with many records):
WITH CTE ( reportID, roleID, list, user2, length )
AS ( SELECT reportID, roleID, CAST( '' AS VARCHAR(8000) ), CAST( '' AS VARCHAR(8000) ), 0
FROM #tbl
GROUP BY reportID, roleID
UNION ALL
SELECT p.reportID, p.roleID, CAST( list +
CASE WHEN length = 0 THEN '' ELSE ', ' END + RTRIM(p.[user2]) AS VARCHAR(8000) ),
CAST(p.[user2] AS VARCHAR(8000)), length + 1
FROM CTE c
INNER JOIN #tbl p
ON c.reportID = p.reportID
and c.roleID = p.roleID
WHERE p.user2 > c.user2 )
SELECT reportID, roleID, list
FROM ( SELECT reportID, roleID, list,
RANK() OVER ( PARTITION BY reportID, roleID ORDER BY length DESC )
FROM CTE ) D ( reportID, roleID, list , rank )
WHERE rank = 1
~~~
Thank you for your help.