The problem with your original query is you are including the classid
in the select
list of data for the PIVOT. You have 8 different classid
values, which will then be grouped by when applying the aggregate function in the pivot.
The problem is that if you exclude the classid and apply the pivot, you will return only one value per student - the one that matches the min(ClsNm)
Since you want to display every class for each student, then you should consider using the row_number()
windowing function instead of classid. If you apply row_number()
and partition the data by the studntNm
, then you will assign an incremented number for each class per student, then when you aggregate the data you will return each row.
The code will be:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(StudntNm)
FROM clsassin
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT ' + @cols + '
from
(
select StudntNm, ClsNm,
row_number() over(partition by StudntNm
order by ClsNm) rn
from clsassin
) x
pivot
(
min(ClsNm)
for StudntNm in (' + @cols + ')
) p '
execute sp_executesql @query;
See SQL Fiddle with Demo. This will give you the result:
| HARRY | MARY | PAUL | SUE | TOM |
----------------------------------------------------
| Algebra | Algebra | Art | Algebra | Algebra |
| French | Spanish | Biology | History | Biology |
| Physics | (null) | Geometry | Physics | French |
| (null) | (null) | (null) | Spanish | (null) |