A consulta que você precisará para obter os resultados em sua pergunta é:
create table StudentResults(StudentID int,Name nvarchar(50),Course nvarchar(50), CourseLevel nvarchar(10));
insert into StudentResults values(1,'John','English','E2'),(1,'John','Maths','E3'),(1,'John','Computing','L2');
select StudentID
,Name
,[Computing]
,[Maths]
,[English]
from StudentResults
pivot(max(CourseLevel) for Course in([Computing],[Maths],[English])
) as p;
Resultado:
StudentID Name Computing Maths English
1 John L2 E3 E2
Embora, como você possa descobrir, isso requer uma codificação rígida dos assuntos. Se sua lista de assuntos provavelmente mudar, essa consulta não será mais adequada.
Se você estiver confortável, poderá remediar isso com SQL dinâmico:
declare @cols as nvarchar(max)
,@query as nvarchar(max);
set @cols = stuff(
(select distinct ','+quotename(Course)
from StudentResults
for xml path(''),type).value('.','nvarchar(max)'
)
,1,1,''
);
set @query = 'select StudentID
,Name
,'[email protected]+'
from StudentResults
pivot (max(CourseLevel) for Course in ('[email protected]+')
) p';
execute (@query);
Idealmente, porém, você simplesmente retornaria um conjunto de dados, como parece estar em sua tabela de origem e deixaria sua camada de relatório (SSRS, por exemplo) lidar com a dinâmica, para a qual é muito mais adequado do que o SQL puro.