Doing SQL Pivot Dynamic Columns with STUFF function but not getting result I desire
Here is SQL Fiddle http://sqlfiddle.com/#!3/241c2/6/0
What can I do to get rid of all the null\empty cells?
I would want the resulting display to be something like this where each column shows a list of classes each student is assigned to without a bunch of blank cells
Tom Harry Mary Sue Paul Algebra Algebra Algebra Algebra Geometry French French Spanish Spanish Art Biology Physics Physics Biology
Edit: request was made to show code here:
create table clsassin
(
ClassID int,
AssignID int,
ClsNm varchar(10),
StudntNm varchar(10),
)
insert into clsassin values (1, 1, 'Algebra', 'Tom')
insert into clsassin values (1, 2, 'Algebra', 'Harry')
insert into clsassin values (1, 3, 'Algebra', 'Mary')
insert into clsassin values (1, 4, 'Algebra', 'Sue')
insert into clsassin values (2, 5, 'Geometry', 'Paul')
insert into clsassin values (3, 6, 'French', 'Harry')
insert into clsassin values (3, 7, 'French', 'Tom')
insert into clsassin values (4, 8, 'Spanish', 'Mary')
insert into clsassin values (4, 9, 'Spanish', 'Sue')
insert into clsassin values (5, 10, 'Art', 'Paul')
insert into clsassin values (6, 11, 'Biology', 'Tom')
insert into clsassin values (6, 12, 'Biology', 'Paul')
insert into clsassin values (7, 13, 'Physics', 'Harry')
insert into clsassin values (7, 14, 'Physics', 'Sue')
insert into clsassin values (8, 15, 'History', 'Sue')
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
, ClassID
from clsassin
) x
pivot
(
min(ClsNm)
for StudntNm in (' + @cols + ')
) p '
execute(@query)
The problem with your original query is you are including the
classid
in theselect
list of data for the PIVOT. You have 8 differentclassid
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 applyrow_number()
and partition the data by thestudntNm
, 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:
See SQL Fiddle with Demo. This will give you the result:
I have used this method to display a summary table from sales such as:
Product,Jan2013,Feb2013,.....
Using the FOR XML PATH('') method returns all the months, but they are not ordered. Can I sort them to follow the correct sequence? I attached my code below: