Something like this:declare @xml XML = '<UserGroupsInfo> <UserGroup name="UG1"> <User>Tom</User> <User>Harry</User> </UserGroup> <UserGroup name="UG2"> <User>Albert</User> </UserGroup> <UserGroup name="UG3"> <User>Jim</User> <User>Sam</User> </UserGroup></UserGroupsInfo>';with Users(UserName, GroupName, rn) as ( select [User].value('.', 'varchar(50)') Name , [User].value('../@name[1]', 'varchar(50)') GroupName , ROW_NUMBER() over( partition by [User].value('../@name[1]', 'varchar(50)') order by (select 1)) as rn from @xml.nodes('/UserGroupsInfo/UserGroup/User') x([User]) )select UG1, UG2, UG3 from Userspivot (max(UserName) for GroupName in (UG1, UG2, UG3)) pvtreturn